summaryrefslogtreecommitdiff
path: root/m68k-unknown-amigaos
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2018-01-13 00:07:35 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2018-07-23 18:41:06 +0100
commitaf2eff8eba15f5fb1d54eb4cf7b8a4de24eb922a (patch)
tree46858e07d115966a29086e26706a0adc430fb7f5 /m68k-unknown-amigaos
parent8614f549b79ac6d9d079efc85a735d0c092ff3e8 (diff)
downloadtoolchains-af2eff8eba15f5fb1d54eb4cf7b8a4de24eb922a.tar.gz
toolchains-af2eff8eba15f5fb1d54eb4cf7b8a4de24eb922a.tar.bz2
Update to gcc 6.4
Diffstat (limited to 'm68k-unknown-amigaos')
-rw-r--r--m68k-unknown-amigaos/Makefile6
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c349
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h45
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.c461
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.h553
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c42
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos30
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/x-amigaos104
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/xm-amigaos.h64
-rw-r--r--m68k-unknown-amigaos/recipes/files/gcc/gcc/doc/gcc-amigaos.texi1116
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p48162
11 files changed, 8148 insertions, 42784 deletions
diff --git a/m68k-unknown-amigaos/Makefile b/m68k-unknown-amigaos/Makefile
index 3aaf896..9ca522a 100644
--- a/m68k-unknown-amigaos/Makefile
+++ b/m68k-unknown-amigaos/Makefile
@@ -3,8 +3,8 @@
# sources
-UPSTREAM_GCC_VERSION := 6.2.0
-UPSTREAM_GCC_TARBALL := gcc-$(UPSTREAM_GCC_VERSION).tar.bz2
+UPSTREAM_GCC_VERSION := 6.4.0
+UPSTREAM_GCC_TARBALL := gcc-$(UPSTREAM_GCC_VERSION).tar.xz
UPSTREAM_GCC_URI := http://ftp.gnu.org/gnu/gcc/gcc-$(UPSTREAM_GCC_VERSION)/$(UPSTREAM_GCC_TARBALL)
UPSTREAM_BINUTILS_VERSION := 2.14
@@ -171,7 +171,7 @@ $(BUILDSTEPS)/srcdir-step2.d: $(BUILDSTEPS)/srcdir-step1.d $(SOURCESDIR)/$(UPSTR
touch $@
$(BUILDSTEPS)/srcdir-step1.d: $(BUILDSTEPS)/$(UPSTREAM_GCC_TARBALL).d
- tar xjf $(SOURCESDIR)/$(UPSTREAM_GCC_TARBALL)
+ tar xJf $(SOURCESDIR)/$(UPSTREAM_GCC_TARBALL)
mv gcc-$(UPSTREAM_GCC_VERSION) $(GCC_SRCDIR)
touch $@
diff --git a/m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c b/m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c
deleted file mode 100644
index 97e5e55..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/* 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);
-}
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
deleted file mode 100644
index dd059f8..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* 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
deleted file mode 100644
index 2c5cab1..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/* 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
deleted file mode 100644
index b1e2660..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.h
+++ /dev/null
@@ -1,553 +0,0 @@
-/* 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
deleted file mode 100644
index aec68d0..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* AmigaOS/m68k host-specific hook definitions.
- Copyright (C) 2003 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
-
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "hosthooks.h"
-#include "hosthooks-def.h"
-#include "toplev.h"
-
-static void * amigaos_m68k_gt_pch_get_address (size_t);
-
-/* Return the address of the PCH address space, if the PCH will fit in it. */
-
-static void *
-amigaos_m68k_gt_pch_get_address (size_t sz ATTRIBUTE_UNUSED)
-{
- fatal_error ("PCH not supported\n");
-}
-
-#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
-#define HOST_HOOKS_GT_PCH_GET_ADDRESS amigaos_m68k_gt_pch_get_address
-
-const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
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
deleted file mode 100644
index 085de81..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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
deleted file mode 100644
index 4409fc5..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/x-amigaos
+++ /dev/null
@@ -1,104 +0,0 @@
-# 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
deleted file mode 100644
index 8b1a3d6..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/xm-amigaos.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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
deleted file mode 100644
index 481c676..0000000
--- a/m68k-unknown-amigaos/recipes/files/gcc/gcc/doc/gcc-amigaos.texi
+++ /dev/null
@@ -1,1116 +0,0 @@
-\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/gcc6.p b/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
index c3dcdb7..6979667 100644
--- a/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
+++ b/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
@@ -1,53 +1,412 @@
-From 64dc72223bfc308f487ea8c70c6f961075cd4f24 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 1 Dec 2016 00:19:04 +0100
-Subject: [PATCH 001/303] @R add support for m68k-*-amiga
-
----
- gcc/Makefile.in | 2 +-
- gcc/amigacollect2.c | 348 ++++++++++++++++++
- gcc/c/c-decl.c | 78 ++++
- gcc/c/c-parser.c | 18 +-
- gcc/c/c-tree.h | 4 +
- gcc/calls.c | 2 +-
- gcc/collect2.c | 31 ++
- gcc/config.gcc | 10 +
- gcc/config/m68k/amigaos-protos.h | 58 +++
- gcc/config/m68k/amigaos.c | 773 +++++++++++++++++++++++++++++++++++++++
- gcc/config/m68k/amigaos.h | 490 +++++++++++++++++++++++++
- gcc/config/m68k/amigaos.opt | 13 +
- gcc/config/m68k/host-amigaos.c | 42 +++
- gcc/config/m68k/m68k.c | 30 +-
- gcc/config/m68k/m68k.h | 5 +
- gcc/config/m68k/m68k.md | 2 +
- gcc/config/m68k/m68kamigaos.h | 424 +++++++++++++++++++++
- gcc/config/m68k/m68kemb.h | 2 +
- gcc/config/m68k/t-amigaos | 30 ++
- gcc/config/m68k/x-amigaos | 104 ++++++
- gcc/config/m68k/xm-amigaos.h | 64 ++++
- gcc/expr.c | 2 +-
- gcc/function.c | 2 +-
- gcc/ipa-chkp.c | 2 +
- gcc/tree-chkp.c | 1 +
- gcc/var-tracking.c | 2 +-
- libstdc++-v3/configure | 4 +
- 27 files changed, 2533 insertions(+), 10 deletions(-)
- create mode 100755 gcc/amigacollect2.c
- create mode 100755 gcc/config/m68k/amigaos-protos.h
- create mode 100755 gcc/config/m68k/amigaos.c
- create mode 100755 gcc/config/m68k/amigaos.h
- create mode 100755 gcc/config/m68k/amigaos.opt
- create mode 100755 gcc/config/m68k/host-amigaos.c
- create mode 100755 gcc/config/m68k/m68kamigaos.h
- create mode 100755 gcc/config/m68k/t-amigaos
- create mode 100755 gcc/config/m68k/x-amigaos
- create mode 100755 gcc/config/m68k/xm-amigaos.h
-
+diff --git a/.cproject b/.cproject
+new file mode 100755
+index 000000000000..6db4cbe2447e
+--- /dev/null
++++ .cproject
+@@ -0,0 +1,188 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
++ <storageModule moduleId="org.eclipse.cdt.core.settings">
++ <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522">
++ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522" moduleId="org.eclipse.cdt.core.settings" name="Debug">
++ <externalSettings/>
++ <extensions>
++ <extension id="org.eclipse.cdt.core.Cygwin_PE" point="org.eclipse.cdt.core.BinaryParser"/>
++ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ </extensions>
++ </storageModule>
++ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
++ <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug">
++ <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522." name="/" resourcePath="">
++ <toolChain id="cdt.managedbuild.toolchain.gnu.cygwin.base.2053847551" name="Cygwin GCC" superClass="cdt.managedbuild.toolchain.gnu.cygwin.base">
++ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.Cygwin_PE" id="cdt.managedbuild.target.gnu.platform.cygwin.base.2091243283" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.cygwin.base"/>
++ <builder buildPath="${workspace_loc:/debugwin}/Debug" id="cdt.managedbuild.target.gnu.builder.cygwin.base.1660320342" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.cygwin.base">
++ <outputEntries>
++ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
++ </outputEntries>
++ </builder>
++ <tool id="cdt.managedbuild.tool.gnu.assembler.cygwin.base.607722454" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.cygwin.base">
++ <option id="gnu.both.asm.option.include.paths.2094451885" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
++ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/amigaos-cross-toolchain/.build-m68k/build/gcc-6/gcc}&quot;"/>
++ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
++ </option>
++ <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1425989952" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
++ </tool>
++ <tool id="cdt.managedbuild.tool.gnu.archiver.cygwin.base.2119049474" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.cygwin.base"/>
++ <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968" name="Cygwin C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base">
++ <option id="gnu.cpp.compiler.option.include.paths.466783605" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
++ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
++ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/gcc-6/libcpp/include}&quot;"/>
++ <listOptionValue builtIn="false" value="&quot;D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc&quot;"/>
++ </option>
++ <option id="gnu.cpp.compiler.option.optimization.level.193715843" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
++ <option id="gnu.cpp.compiler.option.debugging.level.2136883244" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
++ <option id="gnu.cpp.compiler.option.preprocessor.def.807277038" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
++ <listOptionValue builtIn="false" value="IN_GCC=1"/>
++ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
++ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
++ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
++ </option>
++ <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin"/>
++ </tool>
++ <tool id="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604" name="Cygwin C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base">
++ <option id="gnu.c.compiler.option.include.paths.692774379" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
++ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
++ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/gcc-6/libcpp/include}&quot;"/>
++ <listOptionValue builtIn="false" value="&quot;D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc&quot;"/>
++ </option>
++ <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.227992926" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
++ <option id="gnu.c.compiler.option.debugging.level.748883400" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
++ <option id="gnu.c.compiler.option.preprocessor.def.symbols.1982594045" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
++ <listOptionValue builtIn="false" value="IN_GCC=1"/>
++ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
++ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
++ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
++ </option>
++ <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313" superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
++ </tool>
++ <tool id="cdt.managedbuild.tool.gnu.c.linker.cygwin.base.344641511" name="Cygwin C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.cygwin.base"/>
++ <tool id="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base.968200320" name="Cygwin C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base">
++ <option id="gnu.cpp.link.option.libs.260033787" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs"/>
++ <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1537937183" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
++ <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
++ <additionalInput kind="additionalinput" paths="$(LIBS)"/>
++ </inputType>
++ </tool>
++ </toolChain>
++ </folderInfo>
++ <sourceEntries>
++ <entry excluding="ada/|doc/|fortran/|ginclude/|go/|java/|jit/|lto/|objc/|objcp/|po/|testsuite/|config/aarch64/|config/alpha/|config/arc/|config/arm/|config/avr/|config/bfin/|config/c6x/|config/cr16/|config/cris/|config/epiphany/|config/fr30/|config/frv/|config/ft32/|config/h8300/|config/i386/|config/ia64/|config/iq2000/|config/lm32/|config/m32c/|config/m32r/|config/mcore/|config/mep/|config/microblaze/|config/mips/|config/mmix/|config/mn10300/|config/moxie/|config/msp430/|config/nds32/|config/nios2/|config/nvptx/|config/pa/|config/pdp11/|config/rl78/|config/rs6000/|config/rx/|config/s390/|config/sh/|config/sparc/|config/spu/|config/stormy16/|config/tilegx/|config/tilepro/|config/v850/|config/vax/|config/visium/|config/vms/|config/xtensa/" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="gcc"/>
++ </sourceEntries>
++ </configuration>
++ </storageModule>
++ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
++ </cconfiguration>
++ <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.811454954">
++ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.811454954" moduleId="org.eclipse.cdt.core.settings" name="Release">
++ <externalSettings/>
++ <extensions>
++ <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
++ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
++ </extensions>
++ </storageModule>
++ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
++ <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.811454954" name="Release" parent="cdt.managedbuild.config.gnu.cross.exe.release">
++ <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.811454954." name="/" resourcePath="">
++ <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.101222491" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
++ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1798723854" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
++ <builder buildPath="${workspace_loc:/debugwin}/Release" id="cdt.managedbuild.builder.gnu.cross.507087034" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
++ <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
++ <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.1686563067" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
++ <option id="gnu.c.compiler.option.debugging.level.60172226" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
++ <option id="gnu.c.compiler.option.include.paths.696908692" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
++ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
++ </option>
++ <option id="gnu.c.compiler.option.preprocessor.def.symbols.652362073" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
++ <listOptionValue builtIn="false" value="IN_GCC=1"/>
++ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
++ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
++ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
++ </option>
++ <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1150724656" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
++ </tool>
++ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
++ <option id="gnu.cpp.compiler.option.optimization.level.2088586809" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
++ <option id="gnu.cpp.compiler.option.debugging.level.1993778911" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
++ <option id="gnu.cpp.compiler.option.include.paths.1936413739" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
++ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
++ </option>
++ <option id="gnu.cpp.compiler.option.preprocessor.def.625117841" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
++ <listOptionValue builtIn="false" value="IN_GCC=1"/>
++ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
++ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
++ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
++ </option>
++ <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
++ </tool>
++ <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.946489608" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
++ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.738916918" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
++ <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1880308865" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
++ <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
++ <additionalInput kind="additionalinput" paths="$(LIBS)"/>
++ </inputType>
++ </tool>
++ <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1813524686" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
++ <tool id="cdt.managedbuild.tool.gnu.cross.assembler.1395544547" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
++ <option id="gnu.both.asm.option.include.paths.1443815690" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
++ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
++ </option>
++ <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1421786104" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
++ </tool>
++ </toolChain>
++ </folderInfo>
++ <sourceEntries>
++ <entry excluding="src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
++ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
++ </sourceEntries>
++ </configuration>
++ </storageModule>
++ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
++ </cconfiguration>
++ </storageModule>
++ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
++ <project id="debugwin.cdt.managedbuild.target.gnu.cross.exe.1884740625" name="Executable" projectType="cdt.managedbuild.target.gnu.cross.exe"/>
++ </storageModule>
++ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
++ <storageModule moduleId="refreshScope" versionNumber="2">
++ <configuration configurationName="Debug">
++ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
++ </configuration>
++ <configuration configurationName="Release">
++ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
++ </configuration>
++ </storageModule>
++ <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
++ <storageModule moduleId="scannerConfiguration">
++ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
++ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466;cdt.managedbuild.tool.gnu.c.compiler.input.1150724656">
++ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
++ </scannerConfigBuildInfo>
++ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.c.compiler.502147450;cdt.managedbuild.tool.gnu.c.compiler.input.1173428818">
++ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
++ </scannerConfigBuildInfo>
++ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968;cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803">
++ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
++ </scannerConfigBuildInfo>
++ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604;cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313">
++ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
++ </scannerConfigBuildInfo>
++ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.216739552;cdt.managedbuild.tool.gnu.cpp.compiler.input.1269341019">
++ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
++ </scannerConfigBuildInfo>
++ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749;cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092">
++ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
++ </scannerConfigBuildInfo>
++ </storageModule>
++</cproject>
+diff --git a/.project b/.project
+new file mode 100644
+index 000000000000..500c9ee08dca
+--- /dev/null
++++ .project
+@@ -0,0 +1,34 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<projectDescription>
++ <name>gcc-6</name>
++ <comment></comment>
++ <projects>
++ </projects>
++ <buildSpec>
++ <buildCommand>
++ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
++ <triggers>clean,full,incremental,</triggers>
++ <arguments>
++ </arguments>
++ </buildCommand>
++ <buildCommand>
++ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
++ <triggers>full,incremental,</triggers>
++ <arguments>
++ </arguments>
++ </buildCommand>
++ </buildSpec>
++ <natures>
++ <nature>org.eclipse.cdt.core.cnature</nature>
++ <nature>org.eclipse.cdt.core.ccnature</nature>
++ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
++ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
++ </natures>
++ <linkedResources>
++ <link>
++ <name>build-gcc</name>
++ <type>2</type>
++ <location>D:/develop/workspaces/c1/amigaos-cross-toolchain/.build-m68k/build/gcc-6</location>
++ </link>
++ </linkedResources>
++</projectDescription>
+diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
+new file mode 100755
+index 000000000000..caef162d88d1
+--- /dev/null
++++ .settings/language.settings.xml
+@@ -0,0 +1,25 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<project>
++ <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522" name="Debug">
++ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
++ <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
++ <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
++ <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
++ <provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorCygwin" console="false" env-hash="1253352314297216180" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorCygwin" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cygwin" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
++ <language-scope id="org.eclipse.cdt.core.gcc"/>
++ <language-scope id="org.eclipse.cdt.core.g++"/>
++ </provider>
++ </extension>
++ </configuration>
++ <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.811454954" name="Release">
++ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
++ <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
++ <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
++ <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
++ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-910044784883564564" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
++ <language-scope id="org.eclipse.cdt.core.gcc"/>
++ <language-scope id="org.eclipse.cdt.core.g++"/>
++ </provider>
++ </extension>
++ </configuration>
++</project>
+diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs
+new file mode 100755
+index 000000000000..b5248c620107
+--- /dev/null
++++ .settings/org.eclipse.cdt.codan.core.prefs
+@@ -0,0 +1,71 @@
++eclipse.preferences.version=1
++org.eclipse.cdt.codan.checkers.errnoreturn=Warning
++org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
++org.eclipse.cdt.codan.checkers.errreturnvalue=Error
++org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
++org.eclipse.cdt.codan.checkers.nocommentinside=-Error
++org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
++org.eclipse.cdt.codan.checkers.nolinecomment=-Error
++org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
++org.eclipse.cdt.codan.checkers.noreturn=Error
++org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
++org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
++org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
++org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
++org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
++org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
++org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
++org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
++org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
++org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
++org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
++org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
++org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
++org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
++org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
++org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
++org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
++org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
++org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
++org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
++org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
++org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
++org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
++org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
++org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
++org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
++org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
++org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
++org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
++org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
++org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
++org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
++org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
++org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
++org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
++org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
++org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
++org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
++org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
++org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
++org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
++org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
++org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
++org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
++org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
++org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
++org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
++org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
++org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
++org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
++org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
++org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
++org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
+diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
+new file mode 100755
+index 000000000000..8ec9fe72ca59
+--- /dev/null
++++ .settings/org.eclipse.cdt.core.prefs
+@@ -0,0 +1,6 @@
++eclipse.preferences.version=1
++environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/delimiter=;
++environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/operation=replace
++environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/value=C\:\\WINDOWS\\system32;C\:\\WINDOWS;C\:\\Program Files\\SlikSvn\\bin;C\:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0;c\:\\cygwin\\bin;D\:\\develop\\workspaces\\c1\\amigaos-cross-toolchain\\m68k-amigaos\\bin
++environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/append=true
++environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/appendContributed=true
+diff --git a/.settings/org.eclipse.core.runtime.prefs b/.settings/org.eclipse.core.runtime.prefs
+new file mode 100755
+index 000000000000..12511e62a174
+--- /dev/null
++++ .settings/org.eclipse.core.runtime.prefs
+@@ -0,0 +1,5 @@
++content-types/enabled=true
++content-types/org.eclipse.cdt.core.cHeader/file-extensions=def
++content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=h
++content-types/org.eclipse.cdt.core.cxxSource/file-extensions=c
++eclipse.preferences.version=1
+diff --git a/config.sub b/config.sub
+index 41146e11c6c9..35247fe0c474 100755
+--- config.sub
++++ config.sub
+@@ -2,7 +2,7 @@
+ # Configuration validation subroutine script.
+ # Copyright 1992-2016 Free Software Foundation, Inc.
+
+-timestamp='2016-01-01'
++timestamp='2017-04-21'
+
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+@@ -500,7 +500,7 @@ case $basic_machine in
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+- amigaos | amigados)
++ amigaos | amigaosvasm | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+@@ -1380,7 +1380,7 @@ case $os in
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
++ | -clix* | -riscos* | -uniplus* | -iris* | -rt* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
-index 513f9c57013f..c1986279752f 100644
+index 51e2bc86e9a4..4aedf54bab12 100644
--- gcc/Makefile.in
+++ gcc/Makefile.in
-@@ -1985,7 +1985,7 @@ gcc-nm.c: gcc-ar.c
+@@ -1199,6 +1199,7 @@ OBJS = \
+ auto-inc-dec.o \
+ auto-profile.o \
+ bb-reorder.o \
++ bbb-opts.o \
+ bitmap.o \
+ bt-load.o \
+ builtins.o \
+@@ -1986,7 +1987,7 @@ gcc-nm.c: gcc-ar.c
cp $^ $@
COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o \
@@ -56,6 +415,15 @@ index 513f9c57013f..c1986279752f 100644
COLLECT2_LIBS = @COLLECT2_LIBS@
collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
# Don't try modifying collect2 (aka ld) in place--it might be linking this.
+@@ -3270,7 +3271,7 @@ endif
+ install-strip: install
+
+ # Handle cpp installation.
+-install-cpp: installdirs cpp$(exeext)
++install-cpp: installdirs cpp$(exeext) all.cross
+ -if test "$(enable_as_accelerator)" != "yes" ; then \
+ rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
diff --git a/gcc/amigacollect2.c b/gcc/amigacollect2.c
new file mode 100755
index 000000000000..941ea0248fbe
@@ -410,6420 +778,2540 @@ index 000000000000..941ea0248fbe
+ argv[1]=output_file;
+ fork_execute("postlink", (char **)argv, false);
+}
-diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
-index b237e93b927d..3107bdfac430 100644
---- gcc/c/c-decl.c
-+++ gcc/c/c-decl.c
-@@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
- #include "c-family/c-ada-spec.h"
- #include "cilk.h"
- #include "builtins.h"
-+#include "output.h"
-+#include "tm_p.h"
-
- /* In grokdeclarator, distinguish syntactic contexts of declarators. */
- enum decl_context
-@@ -5024,6 +5026,29 @@ grokparm (const struct c_parm *parm, tree *expr)
- return decl;
- }
-
-+#ifdef TARGET_AMIGA
-+
-+/* Create a new variant of TYPE, equivalent but distinct.
-+ This is so the caller can modify it. */
-+
-+static tree
-+build_type_copy (tree type)
-+ {
-+ tree t, m = TYPE_MAIN_VARIANT (type);
-+
-+ t = copy_node (type);
-+
-+ TYPE_POINTER_TO (t) = 0;
-+ TYPE_REFERENCE_TO (t) = 0;
-+
-+ /* Add this type to the chain of variants of TYPE. */
-+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
-+ TYPE_NEXT_VARIANT (m) = t;
-+
-+ return t;
-+ }
-+#endif
-+
- /* Given a parsed parameter declaration, decode it into a PARM_DECL
- and push that on the current scope. EXPR is a pointer to an
- expression that needs to be evaluated for the side effects of array
-@@ -5041,6 +5066,59 @@ push_parm_decl (const struct c_parm *parm, tree *expr)
-
- decl = pushdecl (decl);
-
-+#ifdef TARGET_AMIGAOS
-+ if (parm->asmspec)
-+ {
-+ tree atype = TREE_TYPE(decl);
-+ const char *asmspec = TREE_STRING_POINTER(parm->asmspec);
-+ if (*asmspec == '%')
-+ ++asmspec;
-+ int reg_number = decode_reg_name (asmspec);
-+
-+ /* First detect errors in declaring global registers. */
-+ if (reg_number == -1)
-+ error ("%Jregister name not specified for %qD", decl, decl);
-+ else if (reg_number < 0)
-+ error ("%Jinvalid register name for %qD", decl, decl);
-+ else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
-+ error ("%Jdata type of %qD isn%'t suitable for a register", decl, decl);
-+ else if (!HARD_REGNO_MODE_OK(reg_number, TYPE_MODE (TREE_TYPE (decl))))
-+ error ("%Jregister specified for %qD isn%'t suitable for data type",
-+ decl, decl);
-+ /* Now handle properly declared static register variables. */
-+ else
-+ {
-+ /* Build tree for __attribute__ ((asm(regnum))). */
-+ FIXED_VALUE_TYPE fv =
-+ { reg_number, 0, BImode };
-+ tree ttasm = get_identifier("asm");
-+ tree t, attrs = tree_cons(ttasm, build_fixed (ttasm, fv), NULL_TREE);
-+ /* 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(atype); t; t = TYPE_NEXT_VARIANT(t))
-+ if (comptypes (t, atype) == 1
-+ && attribute_list_equal (TYPE_ATTRIBUTES(t), attrs))
-+ break;
-+ if (t)
-+ atype = 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). */
-+ atype = build_type_copy (atype);
-+ TYPE_ATTRIBUTES(atype) = chainon (attrs, TYPE_ATTRIBUTES(atype));
-+ }
-+ TREE_TYPE(decl) = atype;
-+// printf("%s using %s, cdecl=%p, type=%p\n", IDENTIFIER_POINTER(DECL_NAME (decl), asmspec, decl, atype);
-+ }
-+ }
-+#endif
-+
- finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
- }
-
-diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
-index c9eb8ddbae3a..d8725b572b55 100644
---- gcc/c/c-parser.c
-+++ gcc/c/c-parser.c
-@@ -3837,10 +3837,26 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
- c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- return NULL;
- }
-+ /**
-+ * SBF: Add support for __asm("xy") register spec.
-+ */
-+#ifdef TARGET_AMIGAOS
-+ tree asmspec = NULL_TREE;
-+ if (c_parser_next_token_is_keyword (parser, RID_ASM))
-+ {
-+ asmspec = c_parser_simple_asm_expr (parser);
-+// printf("asmspec: %s\n", TREE_STRING_POINTER(asmspec));
-+ }
-+#endif
- if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
- postfix_attrs = c_parser_attributes (parser);
-- return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
-+
-+ struct c_parm * cparm = build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
- declarator);
-+#ifdef TARGET_AMIGAOS
-+ cparm->asmspec = asmspec;
-+#endif
-+ return cparm;
- }
-
- /* Parse a string literal in an asm expression. It should not be
-diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
-index bb12a200f709..e3404fd8b0a6 100644
---- gcc/c/c-tree.h
-+++ gcc/c/c-tree.h
-@@ -453,6 +453,10 @@ struct c_parm {
- tree attrs;
- /* The declarator. */
- struct c_declarator *declarator;
-+#ifdef TARGET_AMIGAOS
-+ /* The optional asm spec to specify the register. */
-+ tree asmspec;
-+#endif
- };
-
- /* Used when parsing an enum. Initialized by start_enum. */
-diff --git a/gcc/calls.c b/gcc/calls.c
-index 6cc1fc721e45..e5188b93ba94 100644
---- gcc/calls.c
-+++ gcc/calls.c
-@@ -21,12 +21,12 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
- #include "gimple.h"
- #include "predict.h"
--#include "tm_p.h"
- #include "stringpool.h"
- #include "expmed.h"
- #include "optabs.h"
-diff --git a/gcc/collect2.c b/gcc/collect2.c
-index bffac802b8fe..f52a66ef1b58 100644
---- gcc/collect2.c
-+++ gcc/collect2.c
-@@ -1392,6 +1392,11 @@ main (int argc, char **argv)
- 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
-@@ -1492,6 +1497,11 @@ main (int argc, char **argv)
- add_to_list (&libs, arg);
- }
- #endif
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_LIBNAME_HOOK
-+ COLLECT2_LIBNAME_HOOK(arg);
-+#endif
-+ /* end-GG-local */
- }
- }
-
-@@ -1608,6 +1618,11 @@ main (int argc, char **argv)
-
- 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.
-@@ -1648,6 +1663,8 @@ main (int argc, char **argv)
- }
- }
-
-+ /* begin-GG-local: dynamic libraries */
-+#ifndef COLLECT2_POSTLINK_HOOK
- /* Unless we have done it all already, examine the namelist and search for
- static constructors and destructors to call. Write the constructor and
- destructor tables to a .s file and reload. */
-@@ -1674,6 +1691,10 @@ main (int argc, char **argv)
- frame_tables.number),
- frame_tables.number);
- }
-+#else /* COLLECT2_POSTLINK_HOOK */
-+ COLLECT2_POSTLINK_HOOK(output_file);
-+#endif
-+/* end-GG-local */
-
- /* If the scan exposed nothing of special interest, there's no need to
- generate the glue code and relink so return now. */
-@@ -1716,6 +1737,11 @@ main (int argc, char **argv)
-
- 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;
- }
-
-@@ -1821,6 +1847,11 @@ main (int argc, char **argv)
- maybe_unlink (export_file);
- #endif
-
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_EXTRA_CLEANUP
-+ COLLECT2_EXTRA_CLEANUP();
-+#endif
-+ /* end-GG-local */
- return 0;
- }
-
-diff --git a/gcc/config.gcc b/gcc/config.gcc
-index 1d5b23f228d2..3ef1a5f110f3 100644
---- gcc/config.gcc
-+++ gcc/config.gcc
-@@ -1931,6 +1931,16 @@ m68k-*-elf* | fido-*-elf*)
- ;;
- esac
- ;;
-+m68k*-*-amigaos*)
-+ default_m68k_cpu=68000
-+ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
-+ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_CPU_DEFAULT=0"
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
-+ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
-+ extra_objs=amigaos.o
-+ extra_options="${extra_options} m68k/amigaos.opt"
-+ gnu_ld=yes
-+ ;;
- m68k*-*-netbsdelf*)
- default_m68k_cpu=68020
- default_cf_cpu=5475
-diff --git a/gcc/config/m68k/amigaos-protos.h b/gcc/config/m68k/amigaos-protos.h
-new file mode 100755
-index 000000000000..66b553ab568f
---- /dev/null
-+++ gcc/config/m68k/amigaos-protos.h
-@@ -0,0 +1,58 @@
-+/* 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. */
-+
-+#undef TARGET_AMIGAOS
-+#define TARGET_AMIGAOS 1
-+
-+extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree);
-+
-+/* 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)))
-+
-+
-+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_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 *);
-+#endif
-+
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
+diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
new file mode 100755
-index 000000000000..90bc3218bab7
+index 000000000000..9e989e9b1ec0
--- /dev/null
-+++ gcc/config/m68k/amigaos.c
-@@ -0,0 +1,773 @@
-+/* 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).
++++ gcc/bbb-opts.c
+@@ -0,0 +1,4705 @@
++/* Bebbo's Optimizations.
++ Copyright (C) 2010-2017 Free Software Foundation, Inc.
++ Copyright (C) 2017 Stefan "Bebbo" Franke.
+
-+This file is part of GCC.
++ 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 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 3, 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.
++ 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. */
++ You should have received a copy of the GNU General Public License
++ along with GCC; see the file COPYING3. If not see
++ <http://www.gnu.org/licenses/>. */
+
-+//work without flag_writable_strings which is not in GCC4
-+#define REGPARMS_68K 1
++/**
++ * SBF (Stefan "Bebbo" Franke):
++ *
++ * This pass performs multiple optimizations.
++ *
++ * #1 propagate_moves
++ * check if a->b->a can be moved out of a loop.
++ *
++ * #2 strcpy
++ * check if a temp reg can be eliminated.
++ *
++ * #3 const_comp_sub
++ * convert a compare with int constant into sub statement.
++ *
++ * #4 merge_add
++ * merge adds
++ *
++ * #5 elim_dead_assign
++ * eliminate some dead assignments.
++ *
++ * #6 shrink stack frame
++ * remove push/pop for unused variables
++ *
++ * #7 rename register
++ * rename registers without breaking register parameters, inline asm etc.
++ *
++ * Lessons learned:
++ *
++ * - do not trust existing code, better delete insns and inster a new one.
++ * - do not modify insns, create new insns from pattern
++ * - do not reuse registers, create new reg rtx instances
++ *
++ */
+
+#include "config.h"
++#define INCLUDE_VECTOR
++#define INCLUDE_SET
++#define INCLUDE_MAP
+#include "system.h"
+#include "coretypes.h"
-+#include "tm.h"
++#include "backend.h"
++#include "target.h"
+#include "rtl.h"
-+#include "output.h"
-+#include "tree.h"
-+#include "attribs.h"
-+#include "flags.h"
-+#include "expr.h"
-+#include "toplev.h"
+#include "tm_p.h"
-+#include "target.h"
-+#include "diagnostic-core.h"
-+#include "config/m68k/amigaos.h"
-+
-+
-+#if 0
-+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 ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED,
-+ 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 ();
-+}
++#include "insn-config.h"
++#include "recog.h"
++#include "cfgrtl.h"
++#include "emit-rtl.h"
++#include "tree.h"
++#include "tree-pass.h"
++#include "conditions.h"
++#include "langhooks.h"
++#include <vector>
++#include <set>
++#include <map>
+
-+/* 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. */
++int be_very_verbose;
++bool be_verbose;
+
-+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_ELT(TYPE_SIZE (type), 1) == 0
-+ && TREE_INT_CST_LOW (TYPE_SIZE (type)) < 32)
-+ || FLOAT_TYPE_P (type);
-+}
++extern struct lang_hooks lang_hooks;
+
-+/* Record properties of a DECL into the associated SYMBOL_REF. */
++static void
++update_insn_infos (void);
++static unsigned
++track_regs ();
+
-+void
-+amigaos_encode_section_info (tree decl, rtx rtl, int first)
++/* Lookup of the current function name. */
++extern tree current_function_decl;
++static tree last_function_decl;
++static char fxname[512];
++static char const *
++get_current_function_name ()
+{
-+ 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;
++ if (current_function_decl == NULL)
++ strcpy (fxname, "<toplevel>");
+ else
-+ {
-+ if ((MEM_READONLY_P (rtl) && !MEM_VOLATILE_P (rtl)
-+ && (flag_pic<3 || (TREE_CODE (decl) == STRING_CST
-+ )
-+ || amigaos_put_in_text (decl)))
-+ || (TREE_CODE (decl) == VAR_DECL
-+ && DECL_SECTION_NAME (decl) != NULL))
-+ 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");
++ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2));
++ return fxname;
+}
+
-+/* 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)
++/* a simple log to stdout. */
++static int
++log (char const * fmt, ...)
+{
-+ 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 (OPT_Wattributes, "`%s' attribute only applies to variables",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
-+
-+//----- from 68k.c start
-+
-+
-+
-+
-+
-+
-+/* Stack checking and automatic extension support. */
++ if (!be_verbose)
++ return 0;
+
-+void
-+amigaos_prologue_begin_hook (FILE *stream, int fsize)
-+{
-+ if (TARGET_STACKCHECK)
++ va_list args;
++ va_start(args, fmt);
++ if (last_function_decl != current_function_decl)
+ {
-+ 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);
++ last_function_decl = current_function_decl;
++ printf (":bbb: in '%s'\n", get_current_function_name ());
+ }
++ printf (":bbb: ");
++ int retval = vprintf (fmt, args);
++ va_end(args);
++ fflush (stdout);
++ return retval;
+}
+
-+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)
++enum proepis
+{
-+ 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);
-+//}
-+#endif
-+
-+/*
-+ * begin-GG-local: explicit register specification for parameters.
-+ *
-+ * Reworked and ported to gcc-6.2.0 by Stefan "Bebbo" Franke.
-+ */
++ IN_CODE, IN_PROLOGUE, IN_EPILOGUE, IN_EPILOGUE_PARALLEL_POP
++};
+
+/**
-+ * Define this here and add it to tm_p -> all know the custom type and allocate/use the correct size.
++ * What's needed to track values?
+ */
-+struct amigaos_args
-+{
-+ int num_of_regs;
-+ long regs_already_used;
-+ int last_arg_reg;
-+ int last_arg_len;
-+ tree formal_type; /* New field: formal type of the current argument. */
-+};
-+
-+static struct amigaos_args mycum;
-+static CUMULATIVE_ARGS * lastcum;
-+
-+/* 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
-+amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype)
++class track_var
+{
-+ struct amigaos_args * cum = &mycum;
-+ lastcum = cump;
-+ cum->num_of_regs = amigaos_regparm;
-+// printf("amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs); fflush(stdout);
-+
-+ /* 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. */
++ rtx value[FIRST_PSEUDO_REGISTER];
++ unsigned mask[FIRST_PSEUDO_REGISTER];
+
-+ cum->last_arg_reg = -1;
-+ cum->regs_already_used = 0;
++ bool
++ extend (rtx * z, unsigned * mask, machine_mode dstMode, rtx x)
++ {
++ switch (GET_CODE(x))
++ {
++ case CONST_INT:
++ case CONST_FIXED:
++ case CONST_DOUBLE:
++ case SYMBOL_REF:
++ case LABEL_REF:
++ /* these can be used directly. */
++ *z = x;
++ return true;
+
-+ if (fntype)
-+ {
-+ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(fntype)))
-+ cum->num_of_regs = 0;
-+ else
++ case REG:
+ {
-+ tree ratree = lookup_attribute ("regparm", TYPE_ATTRIBUTES(fntype));
-+ cum->num_of_regs = amigaos_regparm ?
-+ amigaos_regparm : AMIGAOS_DEFAULT_REGPARM;
-+ if (ratree)
++ rtx v = value[REGNO(x)];
++ unsigned mr = mask[REGNO(x)];
++ /* try to expand the register. */
++ if (v)
+ {
-+ tree args = TREE_VALUE(ratree);
++ if (dstMode != GET_MODE(v) && (GET_CODE(v) != CONST_INT || mr == (1 << FIRST_PSEUDO_REGISTER)))
++ return false;
+
-+ if (args && TREE_CODE (args) == TREE_LIST)
-+ {
-+ tree val = TREE_VALUE(args);
-+ if (TREE_CODE (val) == INTEGER_CST)
-+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no > 0 && no < AMIGAOS_MAX_REGPARM)
-+ cum->num_of_regs = no;
-+ }
-+ }
++ *mask |= mr;
++ *z = v;
++ return true;
+ }
-+ }
-+ }
-+ 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
-+
-+ 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_t cum_v, machine_mode, const_tree,
-+ bool)
-+{
-+ struct amigaos_args * cum = &mycum;
-+ CUMULATIVE_ARGS *cump = (CUMULATIVE_ARGS *) get_cumulative_args (cum_v);
-+ /* Update the data in CUM to advance over an argument. */
-+
-+ // printf("amigaos_function_arg_advance1 %p\r\n", cump); fflush(stdout);
-+ if (cump != lastcum)
-+ return;
-+
-+ 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;
-+ }
-+
-+ if (cum->formal_type)
-+ cum->formal_type = TREE_CHAIN(cum->formal_type);
-+}
-+
-+/* 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. */
-+
-+static struct rtx_def *
-+_m68k_function_arg (CUMULATIVE_ARGS *, machine_mode, const_tree);
-+
-+static struct rtx_def *
-+_m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
-+{
-+ struct amigaos_args * cum = &mycum;
-+ // printf("m68k_function_arg numOfRegs=%p\r\n", cum);
-+
-+ if (cump != lastcum)
-+ return 0;
-+
-+ 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 */
++ /* store the reg otherwise. */
++ *mask |= (1 << REGNO(x));
++ if (GET_MODE(x) == dstMode)
++ *z = x;
+ else
-+ regbegin = 0; /* Dx */
-+ altregbegin = 8 - regbegin;
-+ len = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
++ *z = gen_rtx_REG (dstMode, REGNO(x));
++ return true;
+ }
-+
-+ if (regbegin != -1)
++ case PLUS:
++ case MINUS:
++ // handle only in combination with const
+ {
-+ 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;
-+ }
-+ }
++ rtx y = XEXP(x, 0);
++ if (GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref (y))
++ return false;
+
-+ if (cum->last_arg_reg != -1)
-+ {
-+ // printf("-> gen_rtx_REG %d\r\n", cum->last_arg_reg);
-+ return gen_rtx_REG (mode, cum->last_arg_reg);
++ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant offset (later).
++ *z = gen_rtx_PLUS(GET_MODE(x), y, XEXP(x, 1));
++ else
++ *z = gen_rtx_MINUS(GET_MODE(x), y, XEXP(x, 1));
++ return true;
+ }
-+ }
-+ return 0;
-+}
-+
-+/* 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_t cum_v, machine_mode mode,
-+ const_tree type, bool)
-+{
-+ struct amigaos_args * cum = &mycum;
-+
-+ // printf("amigaos_function_arg %p\r\n", cum_v.p); fflush(stdout);
-+
-+ CUMULATIVE_ARGS *cump = (CUMULATIVE_ARGS *) get_cumulative_args (cum_v);
-+
-+ if (cump != lastcum)
-+ return 0;
-+
-+ tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
-+ if (asmtree && 0 == strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-+ {
-+ int i;
-+ cum->last_arg_reg = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-+ 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);
-+ }
-+ return _m68k_function_arg (cump, 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 (const_tree type1, const_tree type2)
-+{
-+ printf("amigaos_comp_type_attributes\n");
-+ /* 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))
++ /* memory reads. */
++ case MEM:
+ {
-+ tree attr1 = TYPE_ATTRIBUTES(arg1);
-+ tree attr2 = TYPE_ATTRIBUTES(arg2);
-+ if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr1))))
-+ attr1 = NULL_TREE;
-+ if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr2))))
-+ attr2 = NULL_TREE;
-+ if (attr1 && attr2)
++ rtx m = XEXP(x, 0);
++ switch (GET_CODE(m))
+ {
-+ if (TREE_FIXED_CST_PTR(TREE_VALUE(attr1))->data.low
-+ != TREE_FIXED_CST_PTR(TREE_VALUE(attr2))->data.low)
-+ return 0;
-+ }
-+ else if (attr1 || attr2)
-+ return 0; /* asm attribute only on one side. */
-+ }
-+ if (arg1 || arg2)
-+ return 0; /* different count of parameters. */
-+ }
-+ return 1;
-+}
++ case SYMBOL_REF:
++ case LABEL_REF:
++ /* these can be used directly. */
++ *z = x;
++ return true;
+
-+/* 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). */
-+#if 0
-+static int
-+m68k_comp_type_attributes (tree type1, tree type2)
-+{
++ case REG:
++ if (!extend (&m, mask, dstMode, m))
++ return false;
+
-+ /* 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
-+}
-+#endif
++ *z = gen_rtx_MEM (GET_MODE(x), m);
++ return true;
+
-+/* end-GG-local */
++ case PLUS:
++ case MINUS:
++ // handle only in combination with const
++ {
++ rtx y = XEXP(m, 0);
++ if (!REG_P(y) && GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref (y))
++ return false;
+
++ if (REG_P(y))
++ if (!extend (&y, mask, dstMode, y))
++ return false;
+
-+/* Handle a "regparm", "stkparm" attribute;
-+ arguments as in struct attribute_spec.handler. */
-+tree
-+amigaos_handle_type_attribute (tree *node, tree name, tree args,
-+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-+{
-+ tree nnn = *node;
-+ do { // while (0);
-+// printf("%p with treecode %d\n", node, TREE_CODE(nnn)); fflush(stdout);
-+ if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE
-+ || TREE_CODE (nnn) == 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))
-+ {
-+// printf ("regparm found\n"); fflush(stdout);
++ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant offset (later).
++ m = gen_rtx_PLUS(GET_MODE(m), y, XEXP(m, 1));
++ else
++ m = gen_rtx_MINUS(GET_MODE(m), y, XEXP(m, 1));
+
-+ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ if (args && TREE_CODE (args) == TREE_LIST)
-+ {
-+ tree val = TREE_VALUE(args);
-+// printf ("regparm with val: %d\n", TREE_CODE(val));
-+ if (TREE_CODE (val) == INTEGER_CST)
-+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no < 0 || no > AMIGAOS_MAX_REGPARM)
-+ {
-+ error ("`regparm' attribute: value %d not in [0 - %d]",
-+ no,
-+ AMIGAOS_MAX_REGPARM);
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ error ("invalid argument(s) to `regparm' attribute");
-+ break;
-+ }
-+ }
-+ }
-+ else if (is_attribute_p ("stkparm", name))
-+ {
-+ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ }
-+ else if (is_attribute_p ("stackext", name))
-+ {
-+ if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`stackext' and `interrupt' are mutually exclusive");
-+ break;
++ *z = gen_rtx_MEM (GET_MODE(x), m);
++ return true;
++ }
++ default:
++ return false;
+ }
++ break;
+ }
-+ else if (is_attribute_p ("saveds", name))
++ default:
++ return false;
++ }
++ }
++
++public:
++ track_var (track_var const * o = 0)
++ {
++ if (o)
++ assign (o);
++ else
++ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
+ {
++ value[i] = 0;
++ mask[i] = 0;
+ }
-+ }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER(name));
-+ }
-+ return NULL_TREE;
-+ } while (0);
-+ // error case
-+ *no_add_attrs = true;
-+ return NULL_TREE;
-+}
-+
++ }
+
-+extern bool
-+m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
++ int
++ find_alias (rtx src)
++ {
++ rtx z = 0;
++ unsigned m = 0;
++ if (extend (&z, &m, GET_MODE(src), src))
++ {
++ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
++ {
++ // do not alias small int value from -128 ... 127
++ if (rtx_equal_p (z, value[i]) && (GET_CODE(z) != CONST_INT || INTVAL(z) > 127 || INTVAL(z) < -128))
++ return i;
++ }
++ }
++ return -1;
++ }
++ void
++ invalidate_mem (rtx dst)
++ {
++ rtx z = 0;
++ unsigned m = 0;
++ if (extend (&z, &m, GET_MODE(dst), dst))
++ {
++ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
++ {
++ if (rtx_equal_p (z, value[i]))
++ {
++ value[i] = 0;
++ mask[i] = 0;
++ }
++ }
++ }
++ }
+
-+bool
-+amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
-+ int *total, bool speed)
-+{
-+// printf("outer: %d, opno: %d", outer_code, opno); fflush(stdout);
-+// debug_rtx(x);
-+ bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
-+ *total *= 4;
-+ return r;
-+}
++ rtx
++ get (unsigned regno)
++ {
++ if (regno >= FIRST_PSEUDO_REGISTER)
++ return 0;
+
++ return value[regno];
++ }
+
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-new file mode 100755
-index 000000000000..1a33225ab60f
---- /dev/null
-+++ gcc/config/m68k/amigaos.h
-@@ -0,0 +1,490 @@
-+/* 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.
++ void
++ set (machine_mode mode, unsigned regno, rtx x, unsigned index)
++ {
++ if (regno >= FIRST_PSEUDO_REGISTER)
++ return;
+
-+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.
++ if (mode == SFmode && regno < 16)
++ mode = SImode;
+
-+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.
++ if (!extend (&value[regno], &mask[regno], mode, x))
++ {
++ clear (mode, regno, index);
++ }
++ }
+
-+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. */
++ bool
++ equals (unsigned regno, rtx x)
++ {
++ if (regno >= FIRST_PSEUDO_REGISTER)
++ return false;
+
-+#ifndef TARGET_AMIGAOS
-+#define TARGET_AMIGAOS 1
-+#endif
++ if (x == 0 || value[regno] == 0)
++ return false;
+
-+#if 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
++ rtx z = 0;
++ unsigned m = 0;
++ if (!extend (&z, &m, GET_MODE(x), x))
++ return false;
+
-+/* Call __flush_cache() after building the trampoline: it will call
-+ an appropriate OS cache-clearing routine. */
++ return rtx_equal_p (z, value[regno]);
++ }
+
-+#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)
++ void
++ clear (machine_mode mode, unsigned regno, unsigned index)
++ {
++ if (regno >= FIRST_PSEUDO_REGISTER)
++ return;
+
-+#endif
++ if (mode == SFmode && regno < 16)
++ mode = SImode;
++ value[regno] = gen_rtx_raw_CONST_INT(mode, 0x100000000000000LL | ((long long int ) (regno) << 32) | index);
++ mask[regno] = 1 << FIRST_PSEUDO_REGISTER;
++ }
+
-+/* 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},*/
++ void
++ clear_aftercall (unsigned index)
++ {
++ for (int i = 2; i < FIRST_PSEUDO_REGISTER; ++i)
++ {
++ if (mask[i] && mask[i] < 1 << FIRST_PSEUDO_REGISTER)
++ {
++ value[i] = 0;
++ mask[i] = 0;
++ }
++ }
++ clear (SImode, 0, index);
++ clear (SImode, 1, index);
++ clear (SImode, 8, index);
++ clear (SImode, 9, index);
++ }
+
++ void
++ clear_for_mask (unsigned def, unsigned index)
++ {
++ if (!def)
++ return;
++ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
++ {
++ // register changed or used somehow
++ if ((1 << regno) & def)
++ clear (SImode, regno, index);
++ }
++ }
+
-+/* 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
++ void
++ assign (track_var const * o)
++ {
++ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
++ {
++ value[i] = o->value[i];
++ mask[i] = o->mask[i];
++ }
++ }
+
++ /* only keep common values in both sides. */
++ void
++ merge (track_var * o, unsigned)
++ {
++ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
++ {
++ if (!rtx_equal_p (value[i], o->value[i]))
++ {
++ value[i] = o->value[i] = 0;
++ mask[i] = 0;
++ }
++ }
++ }
+
-+/* Compile with stack extension. */
++ /* true if a merge would not change anything. */
++ bool
++ no_merge_needed (track_var const * o) const
++ {
++ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
++ {
++ if (!rtx_equal_p (value[i], o->value[i]))
++ return false;
++ }
++ return true;
++ }
++};
+
-+#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))))
++/* Information for each insn to detect alive registers. Enough for m68k.
++ * Why a class? Maybe extend it for general usage.
++ *
++ * Track use & def separate to determine starting points.
++ */
++class insn_info
++{
++ rtx_insn * insn; // the insn
+
-+///* 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))))
++// usage flags
++ unsigned myuse; // bit set if registers are used in this statement
++ unsigned hard; // bit set if registers can't be renamed
++ unsigned use; // bit set if registers are used in program flow
++ unsigned def; // bit set if registers are defined here
+
-+/* Compile with a4 restoring in public functions. */
++ enum proepis proepi;
+
-+#define MASK_RESTORE_A4 0x10000000 /* 1 << 28 */
-+#define TARGET_RESTORE_A4 \
-+ ((target_flags & MASK_RESTORE_A4) && TREE_PUBLIC (current_function_decl))
++ bool stack; // part of stack frame insns
+
-+/* Compile with a4 restoring in all functions. */
++// stuff to analyze insns
++ bool label;
++ bool jump;
++ bool call;
++ bool compare;
++ bool dst_mem;
++ bool src_mem;
++ bool dst_plus;
++ bool src_plus;
++ rtx_code src_op;
++ bool src_ee;
++ bool src_2nd;
++ bool src_const;
+
-+#define MASK_ALWAYS_RESTORE_A4 0x8000000 /* 1 << 27 */
-+#define TARGET_ALWAYS_RESTORE_A4 (target_flags & MASK_ALWAYS_RESTORE_A4)
++ machine_mode mode;
+
-+/* Provide a dummy entry for the '-msmall-code' switch. This is used by
-+ the assembler and '*_SPEC'. */
++ rtx dst_reg;
++ rtx dst_mem_reg;
++ rtx dst_symbol;
++ rtx src_reg;
++ rtx src_mem_reg;
++ rtx src_symbol;
++ unsigned dst_mem_addr;
++ int src_intval;
++ unsigned src_mem_addr;
+
-+#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") }
-+
-+#if 0
-+/* Various ABI issues. */
++ bool visited;
+
-+/* This is (almost;-) BSD, so it wants DBX format. */
-+#undef DBX_DEBUGGING_INFO
-+#define DBX_DEBUGGING_INFO
++ int sp_offset;
+
-+/* GDB goes mad if it sees the function end marker. */
++ int dst_autoinc;
++ int src_autoinc;
+
-+#define NO_DBX_FUNCTION_END 1
++// values for all variables - if used
++ track_var * track;
+
-+/* Allow folding division by zero. */
++public:
++ insn_info (rtx_insn * i = 0, enum proepis p = IN_CODE) :
++ insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
++ false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
++ (rtx_code) 0), src_ee (false), src_2nd (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (
++ 0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (
++ 0), visited (false), sp_offset (0), dst_autoinc (0), src_autoinc (0), track (0)
++ {
++ }
+
-+#define REAL_INFINITY
++ track_var *
++ get_track_var ();
+
-+/* 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
++ inline ptrdiff_t
++ operator < (insn_info const & o) const
++ {
++ return this - &o;
++ }
+
-+/* We use A4 for the PIC pointer, not A5, which is the framepointer. */
++ int
++ get_index () const;
+
-+#undef PIC_OFFSET_TABLE_REGNUM
-+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
-+
-+#undef PIC_REG
-+#define PIC_REG 12
++ void
++ plus_to_move (rtx_insn * newinsn);
+
-+/* 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. */
++ void
++ swap_adds (rtx_insn * newinsn, insn_info & ii);
+
-+#undef FRAME_POINTER_REGNUM
-+#define FRAME_POINTER_REGNUM 13
++ void
++ absolute2base (unsigned regno, unsigned base, rtx with_symbol);
+
-+#undef M68K_REGNAME
-+#define M68K_REGNAME(r) ( \
-+ ( ((r) == FRAME_POINTER_REGNUM) \
-+ && frame_pointer_needed) ? \
-+ M68K_FP_REG_NAME : reg_names[(r)])
++ rtx
++ make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool apply);
+
++ inline bool
++ is_compare () const
++ {
++ return compare;
++ }
+
-+/* The AmigaOS ABI does not define how structures should be returned, so,
-+ contrary to 'm68k.h', we prefer a multithread-safe solution. */
++ inline machine_mode
++ get_mode () const
++ {
++ return mode;
++ }
+
-+#undef PCC_STATIC_STRUCT_RETURN
++ inline bool
++ is_dst_reg () const
++ {
++ return dst_reg;
++ }
+
-+/* 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)). */
++ inline bool
++ is_dst_mem () const
++ {
++ return dst_mem;
++ }
+
-+//+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.
-+//+
++ inline bool
++ is_src_mem () const
++ {
++ return src_mem;
++ }
+
-+//poison VAR
-+//#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
++ inline bool
++ is_src_mem_2nd () const
++ {
++ return src_2nd && src_mem;
++ }
+
-+#undef WCHAR_TYPE
-+#define WCHAR_TYPE "unsigned int"
++ inline bool
++ has_dst_memreg () const
++ {
++ return dst_mem_reg;
++ }
+
-+/* 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
++ inline bool
++ has_src_memreg () const
++ {
++ return src_mem_reg;
++ }
+
-+/* 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
++ inline rtx
++ get_dst_symbol () const
++ {
++ return dst_symbol;
++ }
+
-+#undef TARGET_ASM_EH_FRAME_SECTION
-+#define TARGET_ASM_EH_FRAME_SECTION amiga_eh_frame_section
-+#endif
++ inline rtx
++ get_src_symbol () const
++ {
++ return src_symbol;
++ }
++ inline bool
++ has_dst_addr () const
++ {
++ return dst_mem_addr;
++ }
+
-+/* Use sjlj exceptions because dwarf work only on elf targets */
-+#undef DWARF2_UNWIND_INFO
-+#define DWARF2_UNWIND_INFO 0
++ inline bool
++ has_src_addr () const
++ {
++ return src_mem_addr;
++ }
+
++ inline bool
++ is_label () const
++ {
++ return label;
++ }
+
-+/* This is how to output an assembler line that says to advance the
-+ location counter to a multiple of 2**LOG bytes. */
++ inline bool
++ is_jump () const
++ {
++ return jump;
++ }
+
-+#ifndef ALIGN_ASM_OP
-+#define ALIGN_ASM_OP "\t.align\t"
-+#endif
++ inline bool
++ is_call () const
++ {
++ return call;
++ }
+
-+/* 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)
++ inline unsigned
++ get_dst_mem_addr () const
++ {
++ return dst_mem_addr;
++ }
+
-+/* Baserel support. */
++ inline unsigned
++ get_src_mem_addr () const
++ {
++ return src_mem_addr;
++ }
+
-+/* Given that symbolic_operand(X), return TRUE if no special
-+ base relative relocation is necessary */
++ inline bool
++ is_src_reg () const
++ {
++ return src_reg && !src_op;
++ }
+
-+#define LEGITIMATE_BASEREL_OPERAND_P(X) \
-+ (flag_pic >= 3 && read_only_operand (X))
++ inline int
++ get_src_op () const
++ {
++ return src_op;
++ }
+
-+#undef LEGITIMATE_PIC_OPERAND_P
-+#define LEGITIMATE_PIC_OPERAND_P(X) \
-+ (! symbolic_operand (X, VOIDmode) || LEGITIMATE_BASEREL_OPERAND_P (X))
++ inline bool
++ is_src_ee () const
++ {
++ return src_ee;
++ }
+
-+/* 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).
++ inline bool
++ is_src_mem_plus () const
++ {
++ return src_mem && src_plus;
++ }
+
-+ 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'.
++ inline bool
++ is_dst_mem_plus () const
++ {
++ return dst_mem && dst_plus;
++ }
+
-+ 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).
++ inline int
++ get_dst_regno () const
++ {
++ return dst_reg ? REGNO(dst_reg) : -1;
++ }
+
-+ On the Amiga we use this to indicate if references to a symbol should be
-+ absolute or base relative. */
++ inline int
++ get_src_regno () const
++ {
++ return src_reg ? REGNO(src_reg) : -1;
++ }
+
-+#undef TARGET_ENCODE_SECTION_INFO
-+#define TARGET_ENCODE_SECTION_INFO amigaos_encode_section_info
++ inline rtx
++ get_src_reg () const
++ {
++ return src_reg;
++ }
+
-+#define LIBCALL_ENCODE_SECTION_INFO(FUN) \
-+do \
-+ { \
-+ if (flag_pic >= 3) \
-+ SYMBOL_REF_FLAG (FUN) = 1; \
-+ } \
-+while (0)
++ inline rtx
++ get_dst_reg () const
++ {
++ return dst_reg;
++ }
+
-+/* Select and switch to a section for EXP. */
++ inline int
++ get_src_mem_regno () const
++ {
++ return src_mem_reg ? REGNO(src_mem_reg) : -1;
++ }
+
-+//#undef TARGET_ASM_SELECT_SECTION
-+//#define TARGET_ASM_SELECT_SECTION amigaos_select_section
++ inline int
++ get_dst_mem_regno () const
++ {
++ return dst_mem_reg ? REGNO(dst_mem_reg) : -1;
++ }
+
-+/* Preserve A4 for baserel code if necessary. */
++ inline rtx
++ get_src_mem_reg () const
++ {
++ return src_mem_reg;
++ }
+
-+#define EXTRA_SAVE_REG(REGNO) \
-+do { \
-+ if (flag_pic && flag_pic >= 3 && REGNO == PIC_OFFSET_TABLE_REGNUM \
-+ && amigaos_restore_a4()) \
-+ return true; \
-+} while (0)
++ inline rtx
++ get_dst_mem_reg () const
++ {
++ return dst_mem_reg;
++ }
+
-+/* Predicate for ALTERNATE_PIC_SETUP. */
++ inline int
++ get_src_intval () const
++ {
++ return src_intval;
++ }
+
-+#define HAVE_ALTERNATE_PIC_SETUP (flag_pic >= 3)
++ inline int
++ get_dst_intval () const
++ {
++ return dst_mem_addr;
++ }
+
-+/* Make a4 point at data hunk. */
++ inline bool
++ is_src_const () const
++ {
++ return src_const;
++ }
+
-+#define ALTERNATE_PIC_SETUP(STREAM) \
-+ (amigaos_alternate_pic_setup (STREAM))
++ inline void
++ mark_jump ()
++ {
++ jump = true;
++ }
++ inline void
++ mark_call ()
++ {
++ call = true;
++ }
++ inline void
++ mark_label ()
++ {
++ label = true;
++ }
+
-+/* Attribute support. */
++ void
++ fledder (rtx set);
+
-+/* Generate the test of d0 before return to set cc register in 'interrupt'
-+ function. */
++ void
++ fledder_src_mem (rtx src);
+
-+#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)
++ /* update usage. */
++ void
++ update (insn_info & o)
++ {
++ myuse = o.myuse;
++ hard = o.hard;
++ use = o.use;
++ def = o.def;
++ }
+
++ inline rtx_insn *
++ get_insn () const
++ {
++ return insn;
++ }
+
-+/* Stack checking and automatic extension support. */
++ void
++ mark_stack ()
++ {
++ stack = true;
++ }
+
-+#define PROLOGUE_BEGIN_HOOK(STREAM, FSIZE) \
-+ (amigaos_prologue_begin_hook ((STREAM), (FSIZE)))
++ bool
++ is_stack () const
++ {
++ return stack;
++ }
+
-+#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND
++ inline enum proepis
++ in_proepi () const
++ {
++ return proepi;
++ }
+
-+#define ALTERNATE_FRAME_SETUP_F(STREAM, FSIZE) \
-+ (amigaos_alternate_frame_setup_f ((STREAM), (FSIZE)))
++ inline void
++ set_proepi (enum proepis p)
++ {
++ proepi = p;
++ }
+
-+#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND
++ inline void
++ reset_flags ()
++ {
++ label = false;
++ jump = false;
++ compare = false;
++ dst_mem = false;
++ src_mem = false;
++ dst_plus = false;
++ src_plus = false;
++ src_op = (rtx_code) 0;
++ src_ee = false;
++ src_const = false;
+
-+#define ALTERNATE_FRAME_SETUP(STREAM, FSIZE) \
-+ (amigaos_alternate_frame_setup ((STREAM), (FSIZE)))
++ mode = VOIDmode;
+
-+#define HAVE_ALTERNATE_FRAME_DESTR_F(FSIZE) \
-+ (TARGET_STACKEXTEND && current_function_calls_alloca)
++ dst_reg = 0;
++ dst_mem_reg = 0;
++ dst_symbol = 0;
++ src_reg = 0;
++ src_mem_reg = 0;
++ src_symbol = 0;
++ dst_mem_addr = 0;
+
-+#define ALTERNATE_FRAME_DESTR_F(STREAM, FSIZE) \
-+ (asm_fprintf ((STREAM), "\tjra %U__unlk_a5_rts\n"))
++ src_intval = 0;
++ src_mem_addr = 0;
+
-+#define HAVE_ALTERNATE_RETURN \
-+ (TARGET_STACKEXTEND && frame_pointer_needed && \
-+ current_function_calls_alloca)
++ dst_autoinc = 0;
++ src_autoinc = 0;
++ }
+
-+#define ALTERNATE_RETURN(STREAM)
++ inline int
++ get_src_autoinc () const
++ {
++ return src_autoinc;
++ }
+
-+#if 0
-+#define HAVE_restore_stack_nonlocal TARGET_STACKEXTEND
-+#define gen_restore_stack_nonlocal gen_stack_cleanup_call
++ inline int
++ get_dst_autoinc () const
++ {
++ return dst_autoinc;
++ }
+
-+#define HAVE_restore_stack_function TARGET_STACKEXTEND
-+#define gen_restore_stack_function gen_stack_cleanup_call
++ inline bool
++ is_empty ()
++ {
++ return !def && !use && !hard;
++ }
+
-+#define HAVE_restore_stack_block TARGET_STACKEXTEND
-+#define gen_restore_stack_block gen_stack_cleanup_call
++ inline void
++ mark_myuse (int regno)
++ {
++ myuse |= 1 << regno;
++ use |= 1 << regno;
++ }
+
-+#undef TARGET_ALTERNATE_ALLOCATE_STACK
-+#define TARGET_ALTERNATE_ALLOCATE_STACK 1
++ inline void
++ mark_use (int regno)
++ {
++ use |= 1 << regno;
++ }
+
-+#define ALTERNATE_ALLOCATE_STACK(OPERANDS) \
-+do \
-+ { \
-+ amigaos_alternate_allocate_stack (OPERANDS); \
-+ DONE; \
-+ } \
-+while (0)
-+#endif
++ inline void
++ mark_def (int regno)
++ {
++ def |= 1 << regno;
++ }
+
-+/* begin-GG-local: dynamic libraries */
++ inline void
++ mark_hard (int regno)
++ {
++ hard |= 1 << regno;
++ }
+
-+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 *);
++ inline void
++ unset (int regno)
++ {
++ use &= ~(1 << regno);
++ def &= ~(1 << regno);
++ hard &= ~(1 << regno);
++ }
+
-+/* This macro is used to check if all collect2 facilities should be used.
-+ We need a few special ones, like stripping after linking. */
++ inline unsigned
++ get_use () const
++ {
++ return use;
++ }
+
-+#define DO_COLLECTING (do_collecting || amigaos_do_collecting())
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) //new
++ inline unsigned
++ get_myuse () const
++ {
++ return myuse;
++ }
+
-+/* This macro is called in collect2 for every GCC argument name.
-+ ARG is a part of commandline (without '\0' at the end). */
++ inline void
++ set_use (unsigned u)
++ {
++ use = u;
++ }
+
-+#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG)
++ inline unsigned
++ get_def () const
++ {
++ return def;
++ }
++ inline unsigned
++ get_hard () const
++ {
++ return hard;
++ }
+
-+/* 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. */
++ inline bool
++ is_use (int regno)
++ {
++ return (use & (1 << regno)) != 0;
++ }
+
-+#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG)
++ inline bool
++ is_myuse (int regno)
++ {
++ return (myuse & (1 << regno)) != 0;
++ }
+
-+/* This macro is called at collect2 exit, to clean everything up. */
++ inline bool
++ is_def (int regno)
++ {
++ return (def & (1 << regno)) != 0;
++ }
+
-+#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup
++ inline bool
++ is_hard (int regno)
++ {
++ return (hard & (1 << regno)) != 0;
++ }
+
-+/* 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. */
++ inline void
++ clear_hard_def ()
++ {
++ hard = 0;
++ def = 0;
++ }
+
-+#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
-+amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
++ /*
++ * update for previous insn.
++ * - remove regs which are defined here
++ * - add regs which are used here
++ * - reset _def
++ * - restrain _hard to used
++ */
++ inline void
++ updateWith (insn_info const & o)
++ {
++ use &= ~o.def;
++ use |= o.use;
++ def = 0;
++ }
+
-+/* This macro is called just after the first linker invocation, in place of
-+ "nm" and "ldd". OUTPUT_FILE is the executable's filename. */
++ inline insn_info &
++ merge (insn_info const & o)
++ {
++ myuse = o.myuse;
++ use = (use & ~o.def) | o.use;
++ def |= o.def;
++ hard |= o.hard;
++ return *this;
++ }
+
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
-+/* end-GG-local */
++ inline insn_info &
++ or_use (insn_info const & o)
++ {
++ use |= o.myuse | o.def | o.hard;
++ return *this;
++ }
+
-+#endif
++ inline insn_info &
++ drop_def ()
++ {
++ use &= ~def;
++ return *this;
++ }
+
-+/* begin-GG-local: explicit register specification for parameters */
++ inline insn_info &
++ make_hard ()
++ {
++ hard = use | def;
++ return *this;
++ }
+
-+/* Note: this is an extension of m68k_args */
++ inline insn_info &
++ make_clobber ()
++ {
++ hard = use = def = use | def;
++ return *this;
++ }
+
++ inline bool
++ contains (insn_info const & o) const
++ {
++ if (o.def & ~def)
++ return false;
++ if (o.use & ~use)
++ return false;
++ if (o.hard & ~hard)
++ return false;
++ return true;
++ }
+
-+/* 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 AMIGAOS_MAX_REGPARM
-+#define AMIGAOS_MAX_REGPARM 4
++ inline int
++ get_sp_offset () const
++ {
++ return sp_offset;
++ }
+
-+/* The default number of data, address and float registers to use when
-+ user specified '-mregparm' switch, not '-mregparm=<value>' option. */
-+#undef AMIGAOS_DEFAULT_REGPARM
-+#define AMIGAOS_DEFAULT_REGPARM 2
++ inline void
++ set_sp_offset (int sp)
++ {
++ sp_offset = sp;
++ }
+
++ inline bool
++ is_visited () const
++ {
++ return visited;
++ }
+
-+#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))
++ inline void
++ mark_visited ()
++ {
++ visited = true;
++ }
+
-+/* 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) < AMIGAOS_MAX_REGPARM) \
-+ || ((N) >= 8 && (N) < 8 + AMIGAOS_MAX_REGPARM) \
-+ || (TARGET_68881 && (N) >= 16 && (N) < 16 + AMIGAOS_MAX_REGPARM))
++ inline void
++ clear_visited ()
++ {
++ visited = false;
++ }
+
-+/*
-+ 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.
-+*/
++ void
++ scan ();
+
-+extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *cum, tree);
-+extern void amigaos_function_arg_advance (cumulative_args_t, machine_mode, const_tree, bool);
-+extern rtx amigaos_function_arg (cumulative_args_t, machine_mode, const_tree, bool);
-+extern cumulative_args_t amigaos_pack_cumulative_args (CUMULATIVE_ARGS *);
-+extern int amigaos_comp_type_attributes (const_tree, const_tree);
-+extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
++ void
++ scan_rtx (rtx);
+
-+/* 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.) */
++ bool
++ make_post_inc (int regno);
+
-+#undef TARGET_FUNCTION_ARG_ADVANCE
-+#define TARGET_FUNCTION_ARG_ADVANCE amigaos_function_arg_advance
++ void
++ auto_inc_fixup (int regno, int size);
+
-+/* A C expression that controls whether a function argument is passed
-+ in a register, and which register. */
++ /* return bits for alternate free registers. */
++ unsigned
++ get_free_mask () const
++ {
++ if (def & hard)
++ return 0;
+
-+#undef TARGET_FUNCTION_ARG
-+#define TARGET_FUNCTION_ARG amigaos_function_arg
++ if (!def)
++ return 0;
+
-+#undef TARGET_PACK_CUMULATIVE_ARGS
-+#define TARGET_PACK_CUMULATIVE_ARGS(CUM) \
-+ (amigaos_pack_cumulative_args(&(CUM)))
++ unsigned def_no_cc = def & ~(1 << FIRST_PSEUDO_REGISTER);
++ if (def_no_cc > 0x4000)
++ return 0;
+
-+#undef TARGET_COMP_TYPE_ATTRIBUTES
-+#define TARGET_COMP_TYPE_ATTRIBUTES amigaos_comp_type_attributes
++ unsigned mask = def_no_cc - 1;
++ /* more than one register -> don't touch. */
++ if ((mask & ~def) != mask)
++ return 0;
+
++ if (def_no_cc > 0xff)
++ mask &= 0xff00;
+
-+/* end-GG-local */
++ return mask & ~use;
++ }
+
-+#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"); \
-+ if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
-+ error ("-mregparm=x with 1 <= x <= %d\n", AMIGAOS_MAX_REGPARM); \
-+ } \
-+while (0)
++ unsigned
++ get_regbit () const
++ {
++ if (GET_MODE_SIZE(mode) > 4)
++ return 0;
++ return def & ~hard & ~use & 0x7fff;
++ }
+
-+/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-+ affects_type_identity } */
-+#define SUBTARGET_ATTRIBUTES \
-+ { "regparm", 1, 1, true, false, false, amigaos_handle_type_attribute,\
-+ false },
++ void
++ set_insn (rtx_insn * newinsn);
+
-+#define GOT_SYMBOL_NAME ""
++ void
++ a5_to_a7 (rtx a7);
++};
+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS amigaos_rtx_costs
+bool
-+amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-new file mode 100755
-index 000000000000..a9bc80c4f5b6
---- /dev/null
-+++ gcc/config/m68k/amigaos.opt
-@@ -0,0 +1,13 @@
-+
-+mregparm=
-+Target RejectNegative Var(amigaos_regparm) Joined UInteger
-+Pass arguments through registers.
-+
-+noixemul
-+Target RejectNegative
-+Do not use ixemul.library - use libnix instead to link
-+
-+msmall-code
-+Target RejectNegative
-+small code model
-+
-diff --git a/gcc/config/m68k/host-amigaos.c b/gcc/config/m68k/host-amigaos.c
-new file mode 100755
-index 000000000000..8c72d516a378
---- /dev/null
-+++ gcc/config/m68k/host-amigaos.c
-@@ -0,0 +1,42 @@
-+/* AmigaOS/m68k host-specific hook definitions.
-+ Copyright (C) 2003 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA. */
-+
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "hosthooks.h"
-+#include "hosthooks-def.h"
-+#include "toplev.h"
-+
-+static void * amigaos_m68k_gt_pch_get_address (size_t);
-+
-+/* Return the address of the PCH address space, if the PCH will fit in it. */
-+
-+static void *
-+amigaos_m68k_gt_pch_get_address (size_t sz ATTRIBUTE_UNUSED)
++insn_info::make_post_inc (int regno)
+{
-+ fatal_error ("PCH not supported\n");
-+}
-+
-+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
-+#define HOST_HOOKS_GT_PCH_GET_ADDRESS amigaos_m68k_gt_pch_get_address
-+
-+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
-\ No newline at end of file
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 03f474e1b63c..fe3a939e1530 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -166,7 +166,10 @@ static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
- static bool m68k_ok_for_sibcall_p (tree, tree);
- static bool m68k_tls_symbol_p (rtx);
- static rtx m68k_legitimize_address (rtx, rtx, machine_mode);
--static bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+#ifndef TARGET_AMIGAOS
-+static
-+#endif
-+bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
- #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
- static bool m68k_return_in_memory (const_tree, const_tree);
- #endif
-@@ -174,10 +177,12 @@ static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
- static void m68k_trampoline_init (rtx, tree, rtx);
- static int m68k_return_pops_args (tree, tree, int);
- static rtx m68k_delegitimize_address (rtx);
-+#ifndef TARGET_AMIGA
- static void m68k_function_arg_advance (cumulative_args_t, machine_mode,
- const_tree, bool);
- static rtx m68k_function_arg (cumulative_args_t, machine_mode,
- const_tree, bool);
-+#endif
- static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
- static bool m68k_output_addr_const_extra (FILE *, rtx);
- static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
-@@ -322,6 +327,10 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
- #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
- #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128
-
-+#ifdef TARGET_AMIGA
-+#include "amigaos.h"
-+#endif
-+
- static const struct attribute_spec m68k_attribute_table[] =
- {
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-@@ -332,6 +341,9 @@ static const struct attribute_spec m68k_attribute_table[] =
- m68k_handle_fndecl_attribute, false },
- { "interrupt_thread", 0, 0, true, false, false,
- m68k_handle_fndecl_attribute, false },
-+#ifdef SUBTARGET_ATTRIBUTES
-+ SUBTARGET_ATTRIBUTES
-+#endif
- { NULL, 0, 0, false, false, false, NULL, false }
- };
-
-@@ -1419,6 +1431,7 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
- return false;
- }
-
-+#ifndef TARGET_AMIGA
- /* On the m68k all args are always pushed. */
-
- static rtx
-@@ -1440,6 +1453,7 @@ m68k_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
- ? (GET_MODE_SIZE (mode) + 3) & ~3
- : (int_size_in_bytes (type) + 3) & ~3);
- }
-+#endif
-
- /* Convert X to a legitimate function call memory reference and return the
- result. */
-@@ -2172,6 +2186,8 @@ m68k_get_gp (void)
- if (pic_offset_table_rtx == NULL_RTX)
- pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_REG);
-
-+// debug_rtx(pic_offset_table_rtx);
-+
- crtl->uses_pic_offset_table = 1;
-
- return pic_offset_table_rtx;
-@@ -2442,9 +2458,9 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
- {
- gcc_assert (reg);
--
- pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
- pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
-+// debug_rtx(pic_ref);
- }
- else if (GET_CODE (orig) == CONST)
- {
-@@ -2787,7 +2803,10 @@ const_int_cost (HOST_WIDE_INT i)
- }
- }
-
--static bool
-+#ifndef TARGET_AMIGAOS
-+static
-+#endif
-+bool
- m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- int opno ATTRIBUTE_UNUSED,
- int *total, bool speed ATTRIBUTE_UNUSED)
-@@ -4424,6 +4443,7 @@ floating_exact_log2 (rtx x)
- void
- print_operand (FILE *file, rtx op, int letter)
- {
-+// printf("letter: %c\n", letter);
- if (letter == '.')
- {
- if (MOTOROLA)
-@@ -4521,7 +4541,9 @@ m68k_get_reloc_decoration (enum m68k_reloc reloc)
- switch (reloc)
- {
- case RELOC_GOT:
-- if (MOTOROLA)
-+ if (TARGET_AMIGAOS)
-+ return "";
-+ else if (MOTOROLA)
- {
- if (flag_pic == 1 && TARGET_68020)
- return "@GOT.w";
-diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
-index 2aa858fa23b5..74d5aa042059 100644
---- gcc/config/m68k/m68k.h
-+++ gcc/config/m68k/m68k.h
-@@ -971,3 +971,8 @@ extern int m68k_sched_address_bypass_p (rtx_insn *, rtx_insn *);
- extern int m68k_sched_indexed_address_bypass_p (rtx_insn *, rtx_insn *);
-
- #define CPU_UNITS_QUERY 1
-+
-+#if 1
-+extern void default_stabs_asm_out_constructor (rtx, int);
-+extern void default_stabs_asm_out_destructor (rtx, int);
-+#endif
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index ec37bd76f55f..f5b63f43c372 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -7092,6 +7092,8 @@
- operands[1] = gen_rtx_REG (Pmode, PIC_REG);
- return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
- }
-+ else if (TARGET_AMIGAOS)
-+ return "lea (%%pc, __GLOBAL_OFFSET_TABLE_), %0";
- else if (MOTOROLA)
- {
- if (TARGET_COLDFIRE)
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-new file mode 100755
-index 000000000000..0ce599138c7d
---- /dev/null
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -0,0 +1,424 @@
-+/* m68kelf support, derived from m68kv4.h */
++ rtx pattern = PATTERN (insn);
++ rtx_insn * new_insn = make_insn_raw (pattern);
+
-+/* Target definitions for GNU compiler for mc680x0 running AmigaOs
-+ Copyright (C) 1991-2016 Free Software Foundation, Inc.
++ // convert into POST_INC
++ rtx set0 = single_set (new_insn);
++ if (!set0)
++ return false;
+
-+ Written by Ron Guilmette (rfg@netcom.com) and Fred Fish (fnf@cygnus.com).
++ rtx set = set0;
+
-+This file is part of GCC.
++ if (is_compare ())
++ set = SET_SRC(set);
++ rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
+
-+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 3, or (at your option)
-+any later version.
++ if (src_op && get_src_mem_regno () == regno)
++ {
++ if (src_op == NEG || src_op == NOT || src_op == SIGN_EXTEND)
++ mem = XEXP(mem, 0);
++ else
++ mem = XEXP(mem, 1);
++ }
+
-+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.
++ rtx reg = XEXP(mem, 0);
+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING3. If not see
-+<http://www.gnu.org/licenses/>. */
++ XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
+
-+#ifndef TARGET_AMIGA
-+#define TARGET_AMIGA 1
-+#endif
++ if (insn_invalid_p (new_insn, 0))
++ {
++ XEXP(mem, 0) = reg;
++ insn_invalid_p (insn, 0);
++ return 0;
++ }
+
-+#ifndef SWBEG_ASM_OP
-+#define SWBEG_ASM_OP "\t.swbeg\t"
-+#endif
++ SET_INSN_DELETED(insn);
++ (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
++ insn = emit_insn_after (PATTERN (new_insn), insn);
++ insn_invalid_p (insn, 0);
+
-+#undef PIC_REG
-+#define PIC_REG 12
++ return 1;
++}
+
-+#undef FRAME_POINTER_REGNUM
-+#define FRAME_POINTER_REGNUM 13
++static rtx
++add_clobbers (rtx_insn * oldinsn)
++{
++ rtx pattern = PATTERN (oldinsn);
++ if (GET_CODE(pattern) != PARALLEL)
++ return pattern;
+
-+#undef M68K_REGNAME
-+#define M68K_REGNAME(r) ( \
-+ ( ((r) == FRAME_POINTER_REGNUM) \
-+ && frame_pointer_needed) ? \
-+ M68K_FP_REG_NAME : reg_names[(r)])
++ int num_clobbers = 0;
++ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
++ {
++ rtx x = XVECEXP(pattern, 0, j);
++ if (GET_CODE(x) == CLOBBER)
++ ++num_clobbers;
++ }
+
++ if (!num_clobbers)
++ return pattern;
+
++ rtx newpat = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (num_clobbers + 1));
++ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
++ {
++ rtx x = XVECEXP(pattern, 0, j);
++ if (GET_CODE(x) == CLOBBER)
++ XVECEXP(newpat, 0, num_clobbers--) = x;
++ }
+
-+/* Here are three prefixes that are used by asm_fprintf to
-+ facilitate customization for alternate assembler syntaxes.
-+ Machines with no likelihood of an alternate syntax need not
-+ define these and need not use asm_fprintf. */
++ XVECEXP(newpat, 0, 0) = XVECEXP(pattern, 0, 0);
++ return newpat;
++}
+
-+/* The prefix for register names. Note that REGISTER_NAMES
-+ is supposed to include this prefix. Also note that this is NOT an
-+ fprintf format string, it is a literal string */
++void
++insn_info::auto_inc_fixup (int regno, int size)
++{
++// debug_rtx (insn);
++ rtx set0 = single_set (insn);
++ rtx set = set0;
++ if (is_compare ())
++ set = SET_SRC(set);
+
-+#undef REGISTER_PREFIX
-+#define REGISTER_PREFIX ""
++ // add to register
++ if (get_src_regno () == regno)
++ {
++ rtx src = SET_SRC(set);
++ if (get_src_intval () == size)
++ {
++ src_intval = 0;
++ src_plus = false;
++ SET_SRC(set) = XEXP(src, 0);
++ }
++ else
++ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
++ }
++ else if (get_src_mem_regno () == regno)
++ {
++ // src mem used ?
++ rtx mem = SET_SRC(set);
++ if (src_op)
++ {
++ if (MEM_P(XEXP(mem, 0)))
++ mem = XEXP(mem, 0);
++ else
++ mem = XEXP(mem, 1);
++ }
++ rtx plus = XEXP(mem, 0);
+
-+/* The prefix for local (compiler generated) labels.
-+ These labels will not appear in the symbol table. */
++ if (src_mem_addr == (unsigned) size)
++ {
++ XEXP(mem, 0) = XEXP(plus, 0);
++ src_mem_addr = 0;
++ src_plus = false;
++ }
++ else
++ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), src_mem_addr -= size);
++ }
+
-+#undef LOCAL_LABEL_PREFIX
-+#define LOCAL_LABEL_PREFIX "."
++ if (get_dst_mem_regno () == regno)
++ {
++ rtx mem = SET_DEST(set);
++ rtx plus = XEXP(mem, 0);
++ if (dst_mem_addr == (unsigned) size)
++ {
++ XEXP(mem, 0) = XEXP(plus, 0);
++ dst_mem_addr = 0;
++ dst_plus = false;
++ }
++ else
++ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), dst_mem_addr -= size);
++ }
+
-+/* The prefix to add to user-visible assembler symbols. */
++ rtx pattern = add_clobbers (insn);
+
-+#undef USER_LABEL_PREFIX
-+#define USER_LABEL_PREFIX "_"
++ SET_INSN_DELETED(insn);
++ insn = emit_insn_after (pattern, insn);
++}
+
-+/* config/m68k.md has an explicit reference to the program counter,
-+ prefix this by the register prefix. */
++track_var *
++insn_info::get_track_var ()
++{
++ if (!track)
++ track = new track_var ();
++ return track;
++}
+
-+#define ASM_RETURN_CASE_JUMP \
-+ do { \
-+ return "jmp %%pc@(2,%0:w)"; \
-+ } while (0)
++void
++insn_info::scan ()
++{
++ rtx pattern = PATTERN (insn);
++ if (ANY_RETURN_P(pattern))
++ {
++ tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
++ int sz = type ? TREE_INT_CST_LOW(type) : 0;
++ // log ("return size %d\n", sz);
++ if (sz <= 64)
++ {
++ mark_hard (0);
++ mark_myuse (0);
++ if (sz > 32)
++ {
++ mark_hard (1);
++ mark_myuse (1);
++ }
++ }
++ }
++ else if (CALL_P(insn))
++ {
++ /* add mregparm registers. */
++ for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
++ {
++ rtx op, reg;
+
-+/* This is how to output an assembler line that says to advance the
-+ location counter to a multiple of 2**LOG bytes. */
++ if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
++ for (unsigned r = REGNO(reg); r < END_REGNO (reg); ++r)
++ mark_myuse (r);
++ }
++ /* mark scratch registers. */
++ mark_def (0);
++ mark_def (1);
++ mark_def (8);
++ mark_def (9);
++ /* also mark all registers as not renamable */
++ hard = use;
++ }
++ scan_rtx (pattern);
++}
+
-+#ifndef ALIGN_ASM_OP
-+#define ALIGN_ASM_OP "\t.align\t"
-+#endif
++/* scan rtx for registers and set the corresponding flags. */
++void
++insn_info::scan_rtx (rtx x)
++{
++ if (REG_P(x))
++ {
++ for (int n = REG_NREGS(x), r = REGNO(x); n > 0; --n, ++r)
++ mark_myuse (r);
++ return;
++ }
+
-+#undef ASM_OUTPUT_ALIGN
-+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-+do { \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, 1 << (LOG)); \
-+} while (0)
++ if (x == cc0_rtx)
++ {
++ mark_myuse (FIRST_PSEUDO_REGISTER);
++ return;
++ }
+
-+/* Register in which address to store a structure value is passed to a
-+ function. The default in m68k.h is a1. For m68k/SVR4 it is a0. */
++ RTX_CODE code = GET_CODE(x);
+
-+#undef M68K_STRUCT_VALUE_REGNUM
-+#define M68K_STRUCT_VALUE_REGNUM A0_REG
++ /* handle SET and record use and def. */
++ if (code == SET)
++ {
++ unsigned u = use;
++ unsigned mu = myuse;
++ use = myuse = 0;
++ rtx dst = SET_DEST(x);
++ scan_rtx (dst);
++ if (REG_P(dst) || ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG) && REG_P(XEXP(dst, 0))))
++ {
++ def |= use;
++ if ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG))
++ use |= u;
++ else
++ use = u;
++ myuse = mu;
++ }
+
-+/* The static chain regnum defaults to a0, but we use that for
-+ structure return, so have to use a1 for the static chain. */
++ // avoid side effects from myuse -> def, e.g. adding the dst reg to def by src auto inc
++ mu = myuse;
++ myuse = 0;
++ scan_rtx (SET_SRC(x));
++ myuse |= mu;
+
-+#undef STATIC_CHAIN_REGNUM
-+#define STATIC_CHAIN_REGNUM A1_REG
-+#undef M68K_STATIC_CHAIN_REG_NAME
-+#define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a1"
++ int code = GET_CODE(SET_SRC(x));
++ if (code == ASM_OPERANDS)
++ hard |= def | use;
++ return;
++ }
+
-+#define ASM_COMMENT_START "|"
++ if (code == TRAP_IF)
++ {
++ /* mark all registers used. */
++ hard = use = myuse = (1 << FIRST_PSEUDO_REGISTER) - 1;
++ return;
++ }
+
-+/* Define how the m68k registers should be numbered for Dwarf output.
-+ The numbering provided here should be compatible with the native
-+ SVR4 SDB debugger in the m68k/SVR4 reference port, where d0-d7
-+ are 0-7, a0-a8 are 8-15, and fp0-fp7 are 16-23. */
++ const char *fmt = GET_RTX_FORMAT(code);
++ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
++ {
++ if (fmt[i] == 'e')
++ scan_rtx (XEXP(x, i));
++ else if (fmt[i] == 'E')
++ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
++ {
++ unsigned u = use;
++ unsigned mu = myuse;
++ unsigned d = def;
++ scan_rtx (XVECEXP(x, i, j));
++ use |= u;
++ myuse |= mu;
++ def |= d;
++ }
++ }
+
-+#undef DBX_REGISTER_NUMBER
-+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
++ if (code == POST_INC || code == PRE_DEC || code == CLOBBER)
++ def |= myuse;
++}
+
-+#if 0
-+/* SVR4 m68k assembler is bitching on the `comm i,1,1' which askes for
-+ 1 byte alignment. Don't generate alignment for COMMON seems to be
-+ safer until we the assembler is fixed. */
-+#undef ASM_OUTPUT_ALIGNED_COMMON
-+/* Same problem with this one. */
-+#undef ASM_OUTPUT_ALIGNED_LOCAL
-+#endif
++void
++insn_info::fledder_src_mem (rtx src)
++{
++ src_mem = true;
++ rtx mem = XEXP(src, 0);
+
-+#undef ASM_OUTPUT_COMMON
-+#undef ASM_OUTPUT_LOCAL
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+( fputs (".comm ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ",%u\n", (int)(SIZE)))
++ if (GET_CODE(mem) == POST_INC)
++ src_autoinc = 1, mem = XEXP(mem, 0);
++ else if (GET_CODE(mem) == PRE_DEC)
++ src_autoinc = -1, mem = XEXP(mem, 0);
+
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+( fputs (".lcomm ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ",%u\n", (int)(SIZE)))
++ if (REG_P(mem))
++ src_mem_reg = mem;
++ else if (GET_CODE(mem) == CONST_INT)
++ src_mem_addr = INTVAL(mem);
++ else if (GET_CODE(mem) == SYMBOL_REF)
++ src_symbol = mem;
++ else if (GET_CODE(mem) == PLUS)
++ {
++ src_plus = true;
++ rtx reg = XEXP(mem, 0);
++ rtx konst = XEXP(mem, 1);
++ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
++ {
++ src_mem_reg = reg;
++ src_const = true;
++ src_mem_addr = INTVAL(konst);
++ }
++ }
++ else if (GET_CODE(mem) == CONST)
++ {
++ mem = XEXP(mem, 0);
++ if (GET_CODE(mem) == PLUS)
++ {
++ rtx sym = XEXP(mem, 0);
++ if (GET_CODE(sym) == SYMBOL_REF)
++ {
++ src_plus = true;
++ src_symbol = sym;
++ src_mem_addr = INTVAL(XEXP(mem, 1));
++ }
++ }
++ }
++}
+
-+/* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
-+ keep switch tables in the text section. */
-+
-+#define JUMP_TABLES_IN_TEXT_SECTION 1
++/* read the set and grab infos */
++void
++insn_info::fledder (rtx set)
++{
++ if (!set || GET_CODE(set) == PARALLEL)
++ return;
+
-+/* In m68k svr4, using swbeg is the standard way to do switch
-+ table. */
-+#undef ASM_OUTPUT_BEFORE_CASE_LABEL
-+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
-+ fprintf ((FILE), "%s&%d\n", SWBEG_ASM_OP, XVECLEN (PATTERN (TABLE), 1));
-+/* end of stuff from m68kv4.h */
++ rtx dst = SET_DEST(set);
++ rtx src = SET_SRC(set);
+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC "crtend.o%s"
++ if (dst == cc0_rtx)
++ {
++ compare = true;
++ set = src;
++ dst = SET_DEST(set);
++ src = SET_SRC(set);
++ }
+
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC "crtbegin.o%s"
++ if (GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG)
++ dst = XEXP(dst, 0);
+
-+#ifndef BSS_SECTION_ASM_OP
-+#define BSS_SECTION_ASM_OP "\t.section\t.bss"
-+#endif
++ mode = GET_MODE(dst);
++ if (mode == VOIDmode)
++ mode = GET_MODE(src);
+
-+#ifndef ASM_OUTPUT_ALIGNED_BSS
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
-+#endif
++ if (REG_P(dst))
++ {
++ dst_reg = dst;
++ }
++ else if (MEM_P(dst))
++ {
++ dst_mem = true;
++ rtx mem = XEXP(dst, 0);
+
++ if (GET_CODE(mem) == POST_INC)
++ dst_autoinc = 1, mem = XEXP(mem, 0);
++ else if (GET_CODE(mem) == PRE_DEC)
++ dst_autoinc = -1, mem = XEXP(mem, 0);
+
-+/* Specs, switches. */
++ if (REG_P(mem))
++ dst_mem_reg = mem;
++ else if (GET_CODE(mem) == CONST_INT)
++ dst_mem_addr = INTVAL(mem);
++ else if (GET_CODE(mem) == SYMBOL_REF)
++ dst_symbol = mem;
++ else if (GET_CODE(mem) == PLUS)
++ {
++ dst_plus = true;
++ rtx reg = XEXP(mem, 0);
++ rtx konst = XEXP(mem, 1);
++ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
++ {
++ dst_mem_reg = reg;
++ dst_mem_addr = INTVAL(konst);
++ }
++ }
++ else if (GET_CODE(mem) == CONST)
++ {
++ mem = XEXP(mem, 0);
++ if (GET_CODE(mem) == PLUS)
++ {
++ rtx sym = XEXP(mem, 0);
++ if (GET_CODE(sym) == SYMBOL_REF)
++ {
++ dst_plus = true;
++ dst_symbol = sym;
++ dst_mem_addr = INTVAL(XEXP(mem, 1));
++ }
++ }
++ }
++ }
+
-+/* 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'. */
++ /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */
++ rtx alt_src_reg = 0;
++ int code = GET_CODE(src);
++ if (!REG_P(src) && !MEM_P(src) && code != CONST_INT && code != CONST && code != CONST_WIDE_INT && code != CONST_DOUBLE
++ && code != CONST_FIXED && code != CONST_STRING)
++ {
++ src_op = GET_CODE(src);
++ const char *fmt = GET_RTX_FORMAT(code);
++ if (fmt[0] == 'e' && fmt[1] == 'e')
++ {
++ src_ee = true;
++ rtx operand = XEXP(src, 1);
++ if (GET_CODE(operand) == CONST_INT || GET_CODE(operand) == CONST_WIDE_INT)
++ src_const = true, src_intval = INTVAL(operand);
++ else if (REG_P(operand))
++ {
++ alt_src_reg = operand;
++ }
++ else if (MEM_P(operand))
++ {
++ // it' something like reg = op(reg, mem(...))
++ src_2nd = true;
++ fledder_src_mem (operand);
++ }
++ }
++ src = XEXP(src, 0);
++ }
+
++ if (REG_P(src))
++ {
++ src_reg = src;
++ }
++ else if (MEM_P(src))
++ {
++ fledder_src_mem (src);
++ }
++ else if (GET_CODE(src) == CONST_INT)
++ {
++ src_const = true;
++ src_intval = INTVAL(src);
++ }
++ if (alt_src_reg)
++ src_reg = alt_src_reg;
++}
+
++/* create a copy for a reg. Optional specify a new register number. */
++static rtx
++copy_reg (rtx reg, int newregno)
++{
++ if (newregno < 0)
++ newregno = REGNO(reg);
++ rtx x = gen_raw_REG (GET_MODE(reg), newregno);
++ x->jump = reg->jump;
++ x->call = reg->call;
++ x->unchanging = reg->unchanging;
++ x->volatil = reg->volatil;
++ x->in_struct = reg->in_struct;
++ x->used = reg->used;
++ x->frame_related = reg->frame_related;
++ x->return_val = reg->return_val;
+
-+#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)))"); \
-+ builtin_define_std ("amiga"); \
-+ builtin_define_std ("amigaos"); \
-+ builtin_define_std ("AMIGA"); \
-+ builtin_define_std ("MCH_AMIGA"); \
-+ builtin_assert ("system=amigaos"); \
-+ } \
-+ while (0)
++ x->u.reg.attrs = reg->u.reg.attrs;
++ return x;
++}
+
-+#if 0
-+if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
-+ builtin_define ("errno=(*ixemul_errno)"); \
++/* Rename the register plus track all locs to undo these changes. */
++static rtx
++find_reg_by_no (rtx x, unsigned oldregno)
++{
++ if (!x)
++ return 0;
+
-+#endif
++ RTX_CODE code = GET_CODE(x);
+
-+/* Inform the program which CPU we compile for. */
++ const char *fmt = GET_RTX_FORMAT(code);
++ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
++ {
++ if (fmt[i] == 'e')
++ {
++ rtx y = XEXP(x, i);
++ if (REG_P(y))
++ {
++ if (REGNO(y) == oldregno)
++ return y;
++ }
++ else
++ {
++ rtx r = find_reg_by_no (y, oldregno);
++ if (r)
++ return r;
++ }
++ }
++ else if (fmt[i] == 'E')
++ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
++ {
++ rtx z = XVECEXP(x, i, j);
++ rtx r = find_reg_by_no (z, oldregno);
++ if (r)
++ return r;
++ }
++ }
++ return 0;
++}
+
-+//#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__} " \
-+ "%{!ansi:" \
-+ "%{m68020:-Dmc68020} " \
-+ "%{mc68020:-Dmc68020} " \
-+ "%{m68020-40:-Dmc68020} " \
-+ "%{m68020-60:-Dmc68020} " \
-+ "%{m68030:-Dmc68030} " \
-+ "%{m68040:-Dmc68040} " \
-+ "%{m68060:-Dmc68060}} " \
-+ "%{m68020:-D__mc68020__ -D__mc68020} " \
-+ "%{mc68020:-D__mc68020__ -D__mc68020} " \
-+ "%{m68020-40:-D__mc68020__ -D__mc68020} " \
-+ "%{m68020-60:-D__mc68020__ -D__mc68020} " \
-+ "%{m68030:-D__mc68030__ -D__mc68030} " \
-+ "%{m68040:-D__mc68040__ -D__mc68040} " \
-+ "%{m68060:-D__mc68060__ -D__mc68060} " \
-+ "%{noixemul:%{!ansi:%{!std=*:-Dlibnix}%{std=gnu*:-Dlibnix}} -D__libnix -D__libnix__} " \
-+ "%{!noixemul:%{!ansi:%{!std=*:-Dixemul}%{std=gnu*:-Dixemul}} -D__ixemul -D__ixemul__}"
-+
-+/* Translate '-resident' to '-fbaserel' (they differ in linking stage only).
-+ Don't put function addresses in registers for PC-relative code. */
-+
-+#define CC1_SPEC \
-+ "%{resident:-fbaserel} " \
-+ "%{resident32:-fbaserel32} " \
-+ "%{msmall-code:-fno-function-cse}"
-+
-+/* Various -m flags require special flags to the assembler. */
-+
-+#undef ASM_SPEC
-+#define ASM_SPEC \
-+ "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
-+
-+#undef ASM_CPU_SPEC
-+#define ASM_CPU_SPEC \
-+ "%{m68000|mc68000:-m68010} " \
-+ "%{m6802*|mc68020:-m68020} " \
-+ "%{m68030} " \
-+ "%{m68040} " \
-+ "%{m68060}"
-+
-+#define ASM_CPU_DEFAULT_SPEC \
-+ "%{!m680*:%{!mc680*:-m68040}}"
-+
-+/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD
-+ compatible debug hunk.
-+ Also, pass appropriate linker flavours depending on user-supplied
-+ commandline options. */
-+
-+#define LINK_SPEC \
-+ "%{noixemul:-fl libnix} " \
-+ "%{resident*:-amiga-datadata-reloc} " \
-+ "%{resident|fbaserel:-m amiga_bss -fl libb} " \
-+ "%{resident32|fbaserel32:-m amiga_bss -fl libb32} " \
-+ "%{g:-amiga-debug-hunk} " \
-+ "%(link_cpu)"
-+
-+#define LINK_CPU_SPEC \
-+ "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
-+
-+/* Choose the right startup file, depending on whether we use base relative
-+ code, base relative code with automatic relocation (-resident), their
-+ 32-bit versions, libnix, profiling or plain crt0.o. */
-+
-+#undef STARTFILE_SPEC
-+#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}}}"
-+
-+#undef ENDFILE_SPEC
-+#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. */
-+
-+#undef LIB_SPEC
-+#define LIB_SPEC \
-+ "%{!noixemul:" \
-+ "%{p|pg:-lc_p}" \
-+ "%{!p:%{!pg:-lc -lamiga -lc}}}" \
-+ "%{noixemul:" \
-+ "-lnixmain -lnix -lamiga %{mstackcheck|mstackextend:-lstack}}"
-+
-+/* This macro defines names of additional specifications to put in the specs
-+ that can be used in various specifications like CC1_SPEC. Its definition
-+ is an initializer with a subgrouping for each command option.
-+
-+ Each subgrouping contains a string constant, that defines the
-+ specification name, and a string constant that used by the GCC driver
-+ program.
-+
-+ Do not define this macro if it does not need to do anything. */
-+#undef EXTRA_SPECS
-+#define EXTRA_SPECS \
-+ { "asm_cpu", ASM_CPU_SPEC }, \
-+ { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
-+ { "link_cpu", LINK_CPU_SPEC }
-+
-+
-+/* 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. */
++ * Collect some data.
++ */
++static std::vector<insn_info> infos;
++typedef std::vector<insn_info>::iterator insn_info_iterator;
+
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
-+/* end-GG-local */
++// insn->u2.insn_uid -> rtx_insn *
++static std::multimap<int, rtx_insn *> label2jump;
++typedef std::multimap<int, rtx_insn *>::iterator l2j_iterator;
+
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT)
++// index -> index
++static std::multimap<unsigned, unsigned> jump2label;
++typedef std::multimap<unsigned, unsigned>::iterator j2l_iterator;
+
-+#if 0
-+#undef INCLUDE_DEFAULTS
-+#define INCLUDE_DEFAULTS \
-+ { \
-+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, \
-+ GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT, 0 }, \
-+ { GCC_INCLUDE_DIR, "GCC", 0, 0 }, \
-+ { CROSS_INCLUDE_DIR "/../../os-include", "GCC", 0, 0 }, \
-+ { TOOL_INCLUDE_DIR "/../ndk/include", "GCC", 0, 0 }, \
-+ { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 }, \
-+ { 0, 0, 0, 0 } \
-+ }
-+#endif
++static std::map<rtx_insn *, insn_info *> insn2info;
++typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
+
-+#undef FIXED_INCLUDE_DIR
-+#define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../os-include"
++static std::set<unsigned> scan_starts;
++typedef std::set<unsigned>::iterator su_iterator;
+
-diff --git a/gcc/config/m68k/m68kemb.h b/gcc/config/m68k/m68kemb.h
-index 0d8d88c74ea9..29b3e194f12d 100644
---- gcc/config/m68k/m68kemb.h
-+++ gcc/config/m68k/m68kemb.h
-@@ -32,12 +32,14 @@
- #define NEEDS_UNTYPED_CALL 1
-
- /* Target OS builtins. */
-+#ifndef TARGET_OS_CPP_BUILTINS
- #define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__embedded__"); \
- } \
- while (0)
-+#endif
-
- /* Override the default LIB_SPEC from gcc.c. We don't currently support
- profiling, or libg.a. */
-diff --git a/gcc/config/m68k/t-amigaos b/gcc/config/m68k/t-amigaos
-new file mode 100755
-index 000000000000..112d5daa06fb
---- /dev/null
-+++ gcc/config/m68k/t-amigaos
-@@ -0,0 +1,30 @@
-+# Makefile fragment for AmigaOS target.
++static insn_info * info0;
++static unsigned usable_regs;
+
-+# Extra object file linked to the cc1* executables.
-+amigaos.o: $(srcdir)/config/m68k/amigaos.c $(CONFIG_H)
-+ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
++static void
++update_insn2index ()
++{
++ infos.reserve (infos.size () * 8 / 7 + 2);
++ insn2info.clear ();
++ /* needs a separate pass since the insn_infos require fixed addresses for ->get_index() */
++ for (unsigned i = 0; i < infos.size (); ++i)
++ {
++ insn_info & ii = infos[i];
++ insn2info.insert (std::make_pair (ii.get_insn (), &ii));
++ }
++ info0 = &infos[0];
++}
+
-+# Additional target dependent options for compiling libgcc.a. This just
-+# ensures that we don't compile libgcc* with anything other than a
-+# fixed stack.
++static void
++update_label2jump ()
++{
++ update_insn2index ();
+
-+#TARGET_LIBGCC2_CFLAGS = -mfixedstack
++ for (unsigned index = 0; index < infos.size (); ++index)
++ {
++ insn_info & ii = infos[index];
++ if (ii.is_label ())
++ for (l2j_iterator i = label2jump.find (ii.get_insn ()->u2.insn_uid), k = i;
++ i != label2jump.end () && i->first == k->first; ++i)
++ jump2label.insert (std::make_pair (insn2info.find (i->second)->second->get_index (), index));
++ }
++}
+
-+# Support for building multiple version of libgcc.
++int
++insn_info::get_index () const
++{
++ insn_info * ii = &infos[0];
+
-+LIBGCC_MULTI = .; \
-+ libb;@fbaserel \
-+ libm020;@m68020 \
-+ libb/libm020;@fbaserel@m68020 \
-+ libb32/libm020;@fbaserel32@m68020
++ if (ii == info0)
++ {
++ ptrdiff_t diff = ((char const *) this - (char const *) ii);
++ unsigned pos = diff / sizeof(insn_info);
++ if (pos < infos.size ())
++ return pos;
++ }
+
-+### begin-GG-local: dynamic libraries
-+# Extra objects that get compiled and linked to collect2
++// realloc happened...
++ for (unsigned i = 0; i < infos.size (); ++i)
++ if (infos[i].get_insn () == this->insn)
++ return i;
+
-+EXTRA_COLLECT2_OBJS = amigacollect2.o
++// whoops!?
++ return 0;
++}
+
-+# Build supplimentary AmigaOS target support file for collect2
-+amigacollect2.o: amigacollect2.c
-+ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+ -DA2IXDIR_PREFIX=\"$(prefix)/share/a2ixlibrary\" $< $(OUTPUT_OPTION)
-+### end-GG-local
-diff --git a/gcc/config/m68k/x-amigaos b/gcc/config/m68k/x-amigaos
-new file mode 100755
-index 000000000000..a8f60b80f9f4
---- /dev/null
-+++ gcc/config/m68k/x-amigaos
-@@ -0,0 +1,104 @@
-+# Makefile fragment for AmigaOS host
++void
++insn_info::plus_to_move (rtx_insn * newinsn)
++{
++ insn = newinsn;
++ src_op = (rtx_code) 0;
++ src_reg = XEXP(PATTERN (newinsn), 1);
++ insn2info.insert (std::make_pair (insn, this));
++// usage flags did not change
++}
+
-+# 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.
++void
++insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
++{
++ insn = newinsn;
+
-+SYSTEM_HEADER_DIR = $(prefix)/include
++ std::swap (*this, ii);
+
-+# 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).
++ insn2info.insert (std::make_pair (insn, this));
++ insn2info.insert (std::make_pair (ii.insn, &ii));
+
-+#RESIDENT = -m68020 -resident32
++// usage flags did not change
++}
+
-+# 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.
++static
++void
++replace_reg (rtx x, unsigned regno, rtx newreg, int offset)
++{
++ RTX_CODE code = GET_CODE(x);
++ const char *fmt = GET_RTX_FORMAT(code);
++ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
++ {
++ if (fmt[i] == 'e')
++ {
++ rtx y = XEXP(x, i);
++ if (REG_P(y) && REGNO(y) == regno)
++ {
++ XEXP(x, i) = newreg;
++ if (offset && i + 1 < GET_RTX_LENGTH(code))
++ {
++ rtx c = XEXP(x, i + 1);
++ if (GET_CODE(c) == CONST_INT)
++ XEXP(x, i + 1) = gen_rtx_CONST_INT (GET_MODE(x), INTVAL(c) + offset);
++ }
++ }
++ else
++ replace_reg (y, regno, newreg, offset);
++ }
++ else if (fmt[i] == 'E')
++ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
++ replace_reg (XVECEXP(x, i, j), regno, newreg, offset);
++ }
++}
+
-+XCFLAGS = -mstackextend $(RESIDENT)
++void
++insn_info::a5_to_a7 (rtx a7)
++{
++ if (proepi == IN_EPILOGUE && src_mem_reg && get_src_mem_regno () == FRAME_POINTER_REGNUM)
++ {
++ rtx set = single_set (insn);
++ if (set)
++ {
++ SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC(SImode, a7));
++ return;
++ }
++ }
++ replace_reg (PATTERN (insn), FRAME_POINTER_REGNUM, a7, -4);
++}
+
-+# AmigaOS supports "AmigaGuide(R)" hypertext files. For GCC, these are
-+# build with a custom "makeinfo".
++void
++insn_info::set_insn (rtx_insn * newinsn)
++{
++ insn = newinsn;
+
-+# Arrange for guides to be build with GCC, in the build directory.
++ reset_flags ();
+
-+### begin-GG-local: gcc-amigaos
-+#EXTRA_DOC_TARGETS = guide gcc-amigaos-doc
-+### end-GG-local
++ fledder (single_set (insn));
++}
+
-+# Actually build guides
++rtx
++insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool apply)
++{
++ rtx set = single_set (get_insn ());
++ rtx src = SET_SRC(set);
++ rtx dst = SET_DEST(set);
++ rtx reg = gen_raw_REG (SImode, regno);
++ bool vola = src->volatil;
+
-+guide:: doc/cpp.guide doc/gcc.guide doc/gccint.guide \
-+ doc/gccinstall.guide doc/cppinternals.guide
++ if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) && !has_dst_memreg () && get_dst_symbol () == with_symbol)
++ {
++ unsigned addr = get_dst_mem_addr ();
++ unsigned offset = addr - base;
++ if (offset <= 0x7ffe)
++ {
++ if (base == addr)
++ dst = gen_rtx_MEM (mode, reg);
++ else
++ dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
+
-+doc/cpp.guide: $(TEXI_CPP_FILES)
-+doc/gcc.guide: $(TEXI_GCC_FILES)
-+doc/gccint.guide: $(TEXI_GCCINT_FILES)
-+doc/cppinternals.guide: $(TEXI_CPPINT_FILES)
++ if (apply)
++ {
++ dst_mem_reg = reg;
++ dst_mem = true;
++ dst_mem_addr = offset;
++ dst_plus = offset != 0;
++ }
++ }
++ }
+
-+doc/%.guide: %.texi
-+ if [ x$(BUILD_INFO) = xinfo ]; then \
-+ $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \
-+ -I $(docdir)/include -o $@ $<; \
-+ fi
++ if (is_src_mem () && (has_src_addr () || get_src_symbol ()) && !has_src_memreg () && get_src_symbol () == with_symbol)
++ {
++ unsigned addr = get_src_mem_addr ();
++ unsigned offset = addr - base;
++ if (offset <= 0x7ffe)
++ {
++ if (base == addr)
++ src = gen_rtx_MEM (mode, reg);
++ else
++ src = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
+
-+# 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
++ /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */
++ if (src_op)
++ {
++ if (src_ee)
++ src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
++ else
++ {
++ if (src_op == SIGN_EXTEND)
++ {
++ PUT_MODE_RAW(src, mode == SImode ? HImode : mode == HImode ? QImode : SImode);
++ src->call = 1;
++ }
++ src = gen_rtx_fmt_e(src_op, mode, src);
++ }
++ }
+
-+# Arrange for guides to be installed with GCC.
++ if (apply)
++ {
++ src_mem_reg = reg;
++ src_mem = true;
++ src_mem_addr = offset;
++ src_plus = offset != 0;
++ }
++ }
++ }
+
-+### begin-GG-local: gcc-amigaos
-+#EXTRA_INSTALL_TARGETS = install-guide install-gcc-amigaos-doc
-+### end-GG-local
++ rtx pattern = gen_rtx_SET(dst, src);
++ src->volatil = vola;
+
-+# Where the guide files go
++ return pattern;
++}
+
-+guidedir = $(prefix)/guide
++void
++insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
++{
++ rtx pattern = make_absolute2base (regno, base, with_symbol, true);
+
-+# Actually install guides.
++ SET_INSN_DELETED(insn);
++ insn = emit_insn_after (pattern, insn);
+
-+installdirs-guide:
-+ $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(guidedir)
++ mark_myuse (regno);
+
-+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
++ insn2info.insert (std::make_pair (insn, this));
++}
++/*
++ * Reset collected data.
++ */
++static void
++clear (void)
++{
++ label2jump.clear ();
++ jump2label.clear ();
++ insn2info.clear ();
++ infos.clear ();
++ scan_starts.clear ();
++}
+
-+$(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
++/*
++ * return true if the register is DEAD.
++ * Do not check at jumps.
++ */
++static bool
++is_reg_dead (unsigned regno, unsigned _pos)
++{
++// skip labels.
++ for (unsigned pos = _pos + 1; pos < infos.size (); ++pos)
++ {
++ insn_info & ii = infos[pos];
++ // skip entries without info
++ if (ii.is_empty ())
++ continue;
+
-+### begin-GG-local: gcc-amigaos
-+# Build and install gcc-amigaos.guide - documentation specific to the
-+# AmigaOS port of GCC.
++ // not dead if usage is reported in the next statement
++ return !ii.is_use (regno) && !ii.is_hard (regno);
++ }
++ return true;
++}
+
-+gcc-amigaos-doc:: doc/gcc-amigaos.info doc/gcc-amigaos.guide
++bool dump_reg_track;
++void
++append_reg_cache (FILE * f, rtx_insn * insn)
++{
++ i2i_iterator i = insn2info.find (insn);
++ if (i == insn2info.end ())
++ return;
+
-+doc/gcc-amigaos.info doc/gcc-amigaos.guide: gcc-amigaos.texi
++ insn_info & jj = *i->second;
++ unsigned index = jj.get_index ();
++ if (index + 1 < infos.size ())
++ ++index;
++ insn_info & ii = infos[index];
+
-+install-gcc-amigaos-doc: doc installdirs installdirs-guide \
-+ $(DESTDIR)$(infodir)/gcc-amigaos.info \
-+ $(DESTDIR)$(guidedir)/gcc-amigaos.guide
-+### end-GG-local
++ track_var * track = ii.get_track_var ();
++ if (track == 0)
++ return;
+
-+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/gcc/config/m68k/xm-amigaos.h b/gcc/config/m68k/xm-amigaos.h
-new file mode 100755
-index 000000000000..bb571ba040b3
---- /dev/null
-+++ gcc/config/m68k/xm-amigaos.h
-@@ -0,0 +1,64 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch).
++ fprintf (f, "\n");
+
-+This file is part of GCC.
++ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
++ {
++ rtx v = track->get (regno);
++ if (v == 0)
++ continue;
+
-+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.
++// if (GET_CODE(v) == CONST_INT && GET_MODE(v) == VOIDmode)
++// continue;
+
-+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.
++ fprintf (f, "%s=", reg_names[regno]);
+
-+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. */
++ print_inline_rtx (f, v, 12);
++ fprintf (f, "\n");
++ }
++}
+
-+#ifndef _FCNTL_H_
-+#include <fcntl.h>
-+#endif
++/* helper stuff to enhance the asm output. */
++int my_flag_regusage;
++void
++append_reg_usage (FILE * f, rtx_insn * insn)
++{
++ i2i_iterator i = insn2info.find (insn);
++ if (i == insn2info.end ())
++ return;
+
-+/* 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. */
++ insn_info & ii = *i->second;
+
-+#define SYSTEM_INCLUDE_DIR "/gg/os-include"
-+#define STANDARD_INCLUDE_DIR "/gg/include"
++ if (f != stderr)
++ {
++ if (be_very_verbose > 1)
++ fprintf (f, "\n\t\t\t\t\t|%d\t", ii.get_index ());
++ else
++ fprintf (f, "\n\t\t\t\t\t|\t");
++ }
+
-+#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/"
++ fprintf (f, "%c ", ii.in_proepi () == IN_PROLOGUE ? 'p' : ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
+
-+/* The AmigaOS stores file names with regard to upper/lower case, but actions
-+ on existing files are case independent on the standard filesystems.
++ for (int j = 0; j < 8; ++j)
++ if (ii.is_use (j) || ii.is_def (j))
++ {
++ fprintf (f, ii.is_hard (j) ? "!" : " ");
++ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse (j) ? "." : " ");
++ fprintf (f, "d%d ", j);
++ }
++ else
++ fprintf (f, " ");
+
-+ 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.
++ for (int j = 8; j < 16; ++j)
++ if (ii.is_use (j) || ii.is_def (j))
++ {
++ fprintf (f, ii.is_hard (j) ? "!" : " ");
++ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse (j) ? "." : " ");
++ fprintf (f, "a%d ", j - 8);
++ }
++ else
++ fprintf (f, " ");
+
-+ 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. */
++ if (ii.is_use (FIRST_PSEUDO_REGISTER))
++ fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "+cc " : " cc ");
++ else
++ fprintf (f, " ");
+
-+#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE))
++ // append fp usage info if present
++ if ((ii.get_use () | ii.get_def ()) & ~0xffff)
++ {
++ for (int j = 16; j < 24; ++j)
++ if (ii.is_use (j) || ii.is_def (j))
++ {
++ fprintf (f, ii.is_hard (j) ? "!" : " ");
++ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse (j) ? "." : " ");
++ fprintf (f, "f%d ", j - 16);
++ }
++ else
++ fprintf (f, " ");
++ }
+
-+/* 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. */
++ if (f == stderr)
++ fprintf (f, "\n");
+
-+#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. */
++/*
++ * Helper function to dump the code.
++ * Sometimes used during debugging.
++ */
++static void
++dump_insns (char const * name, bool all)
++{
++ fprintf (stderr, "====================================: %s\n", name);
++ if (all)
++ {
++ for (rtx_insn * insn = get_insns (); insn && insn != infos[0].get_insn (); insn = NEXT_INSN (insn))
++ debug_rtx (insn);
++ }
++ for (unsigned i = 0; i < infos.size (); ++i)
++ {
++ fprintf (stderr, "%d: ", i);
+
-+#undef PREFIX_INCLUDE_DIR
-diff --git a/gcc/expr.c b/gcc/expr.c
-index eb77ba0fe533..a2e6a7cac927 100644
---- gcc/expr.c
-+++ gcc/expr.c
-@@ -21,12 +21,12 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
- #include "gimple.h"
- #include "predict.h"
--#include "tm_p.h"
- #include "ssa.h"
- #include "expmed.h"
- #include "optabs.h"
-diff --git a/gcc/function.c b/gcc/function.c
-index 401f8f90160d..0c35f094f4cb 100644
---- gcc/function.c
-+++ gcc/function.c
-@@ -35,13 +35,13 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
- #include "gimple-expr.h"
- #include "cfghooks.h"
- #include "df.h"
--#include "tm_p.h"
- #include "stringpool.h"
- #include "expmed.h"
- #include "optabs.h"
-diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
-index 86c48f14f64d..dc72a5f21021 100644
---- gcc/ipa-chkp.c
-+++ gcc/ipa-chkp.c
-@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
-+#include "target.h"
- #include "tree.h"
- #include "gimple.h"
- #include "tree-pass.h"
-diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
-index 4ca2d34607c6..472e203306b8 100644
---- gcc/tree-chkp.c
-+++ gcc/tree-chkp.c
-@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
-diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
-index 9f09d30b1f91..149c0c123804 100644
---- gcc/var-tracking.c
-+++ gcc/var-tracking.c
-@@ -89,13 +89,13 @@
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
- #include "cfghooks.h"
- #include "alloc-pool.h"
- #include "tree-pass.h"
--#include "tm_p.h"
- #include "insn-config.h"
- #include "regs.h"
- #include "emit-rtl.h"
-diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
-index bbbcd5d7ce0c..c8ce02987284 100755
---- libstdc++-v3/configure
-+++ libstdc++-v3/configure
-@@ -28820,6 +28820,10 @@ else
-
- # Base decisions on target environment.
- case "${host}" in
-+ m68k-*-*)
-+ # Nothing to do here.
-+ ;;
++ rtx_insn * insn = infos[i].get_insn ();
++ if (i < infos.size ())
++ append_reg_usage (stderr, insn);
+
- arm*-*-symbianelf*)
- # This is a freestanding configuration; there is nothing to do here.
- ;;
-
-From 6951210c6e4901b5e963a19f5cae44bc0560a915 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 15 Dec 2016 00:37:25 +0100
-Subject: [PATCH 002/303] @N add .project file
-
----
- .project | 11 +++++++++++
- 1 file changed, 11 insertions(+)
- create mode 100644 .project
-
-diff --git a/.project b/.project
-new file mode 100644
-index 000000000000..ab5c4b198d08
---- /dev/null
-+++ .project
-@@ -0,0 +1,11 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<projectDescription>
-+ <name>gcc-6</name>
-+ <comment></comment>
-+ <projects>
-+ </projects>
-+ <buildSpec>
-+ </buildSpec>
-+ <natures>
-+ </natures>
-+</projectDescription>
-
-From c81713312a097d40d212a5ac5bce13b1aff7b226 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 11 Jan 2017 12:09:34 +0100
-Subject: [PATCH 003/303] @B support named sections
-
----
- gcc/config/m68k/amigaos.c | 8 ++++++++
- gcc/config/m68k/amigaos.h | 17 ++++++++++-------
- 2 files changed, 18 insertions(+), 7 deletions(-)
- mode change 100755 => 100644 gcc/config/m68k/amigaos.c
- mode change 100755 => 100644 gcc/config/m68k/amigaos.h
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-old mode 100755
-new mode 100644
-index 90bc3218bab7..facb57a28aa3
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -771,3 +771,11 @@ amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
- }
-
-
-+/* Output assembly to switch to section NAME with attribute FLAGS. */
++ fprintf (stderr, "\t");
++ debug_rtx (insn);
+
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
-+{
-+ fprintf (asm_out_file, "\t.section\t%s\n", name);
++ if (all)
++ {
++ rtx_insn * p = i + 1 < infos.size () ? infos[i + 1].get_insn () : 0;
++ for (rtx_insn * q = NEXT_INSN (insn); q && q != p; q = NEXT_INSN (q))
++ debug_rtx (q);
++ }
++ }
+}
+
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-old mode 100755
-new mode 100644
-index 1a33225ab60f..d347a9be63db
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -113,7 +113,15 @@ Boston, MA 02111-1307, USA. */
- N_("Restore a4 in all functions") }, \
- { "no-always-restore-a4", - MASK_ALWAYS_RESTORE_A4, \
- N_("Do not restore a4 in all functions") }
--
++/* This is the important function to track register usage plus hard/live state.
++ *
++ * Start at bottom and work upwards. On all labels trigger all jumps referring to this label.
++ * A set destination into a register is a def. All other register references are an use.
++ * Hard registers cann't be renamed and are mandatory for regparms and asm_operands.
++ */
++static void
++update_insn_infos (void)
++{
++ /* add all return (jump outs) and start analysis there. */
++ std::set<unsigned> & todo = scan_starts;
+
++ if (todo.begin () == todo.end ())
++ todo.insert (infos.size () - 1);
+
-+/* Support sections in chip memory, currently '.datachip' only. */
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl);
++ bool locka4 = flag_pic >= 3;
+
-+#undef TARGET_ASM_NAMED_SECTION
-+#define TARGET_ASM_NAMED_SECTION amiga_named_section
++ while (!todo.empty ())
++ {
++ int start = *todo.begin ();
++ todo.erase (todo.begin ());
++ insn_info ii = infos[start];
+
- #if 0
- /* Various ABI issues. */
-
-@@ -139,9 +147,6 @@ Boston, MA 02111-1307, USA. */
- #undef PIC_OFFSET_TABLE_REGNUM
- #define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
-
--#undef PIC_REG
--#define PIC_REG 12
--
- /* 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. */
-
-@@ -182,9 +187,7 @@ Boston, MA 02111-1307, USA. */
-
- /* 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
++ enum proepis proepi = ii.in_proepi ();
+
-
- /* We define TARGET_ASM_NAMED_SECTION, but we don't support arbitrary sections,
- including '.gcc_except_table', so we emulate the standard behaviour. */
-
-From 6a04e2c9671b3d0d0de708cd0eb9fdb9bb4d5811 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 12 Jan 2017 00:10:47 +0100
-Subject: [PATCH 004/303] @B fix null ptr
-
----
- gcc/config/m68k/amigaos.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index facb57a28aa3..8727c7184812 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -508,7 +508,7 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
- /* FIXME: Two last conditions below are workarounds for bugs. */
- else if (INTEGRAL_MODE_P (mode) && mode != CQImode && mode != CHImode)
- {
-- if (POINTER_TYPE_P(type))
-+ if (!type || POINTER_TYPE_P(type))
- regbegin = 8; /* Ax */
- else
- regbegin = 0; /* Dx */
-
-From 09a2cda05b28a749e39d8e0af34ef3556eb21d6a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 12 Jan 2017 00:12:11 +0100
-Subject: [PATCH 005/303] @I added quirky -fbaserel -fbaserel32 - really
- working? nut sure...
-
----
- gcc/config/m68k/amigaos.h | 2 +-
- gcc/config/m68k/amigaos.opt | 7 +++++++
- gcc/config/m68k/m68k.c | 20 +++++++++++---------
- 3 files changed, 19 insertions(+), 10 deletions(-)
- mode change 100755 => 100644 gcc/config/m68k/amigaos.opt
-
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index d347a9be63db..fd89bb34352c 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -471,7 +471,7 @@ extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
- #define SUBTARGET_OVERRIDE_OPTIONS \
- do \
- { \
-- if (!TARGET_68020 && flag_pic==4) \
-+ if (!TARGET_68020 && flag_pic==2) \
- error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \
- if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
- error ("-mregparm=x with 1 <= x <= %d\n", AMIGAOS_MAX_REGPARM); \
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-old mode 100755
-new mode 100644
-index a9bc80c4f5b6..4298bc90abe1
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -11,3 +11,10 @@ msmall-code
- Target RejectNegative
- small code model
-
-+fbaserel
-+Target Common Report Var(flag_pic,3) Negative(fpie) Init(-1)
-+Backward compatibility, use -fpic now
++ // mark sp reg as used.
++ if (proepi >= IN_EPILOGUE)
++ ii.mark_use (STACK_POINTER_REGNUM), infos[start].mark_use (STACK_POINTER_REGNUM);
+
-+fbaserel32
-+Target Common Report Var(flag_pic,4) Negative(fPIE) Init(-1)
-+Backward compatibility, use -fPIC now
-\ No newline at end of file
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index fe3a939e1530..ce28681c1dc9 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -557,7 +557,7 @@ m68k_option_override (void)
- : (m68k_cpu_flags & FL_COLDFIRE) != 0 ? FPUTYPE_COLDFIRE
- : FPUTYPE_68881);
-
-- /* Sanity check to ensure that msep-data and mid-sahred-library are not
-+ /* Sanity check to ensure that msep-data and mid-shared-library are not
- * both specified together. Doing so simply doesn't make sense.
- */
- if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
-@@ -568,7 +568,7 @@ m68k_option_override (void)
- * -fpic but it hasn't been tested properly.
- */
- if (TARGET_SEP_DATA || TARGET_ID_SHARED_LIBRARY)
-- flag_pic = 2;
-+ flag_pic = TARGET_68020 ? 2 : 1;
-
- /* -mpcrel -fPIC uses 32-bit pc-relative displacements. Raise an
- error if the target does not support them. */
-@@ -1139,9 +1139,9 @@ m68k_expand_prologue (void)
- current_frame.reg_mask, true, true));
- }
-
-- if (!TARGET_SEP_DATA
-- && crtl->uses_pic_offset_table)
-- emit_insn (gen_load_got (pic_offset_table_rtx));
-+// if (!TARGET_SEP_DATA
-+// && crtl->uses_pic_offset_table)
-+// emit_insn (gen_load_got (pic_offset_table_rtx));
- }
-
- /* Return true if a simple (return) instruction is sufficient for this
-@@ -4693,8 +4693,10 @@ print_operand_address (FILE *file, rtx addr)
- {
- struct m68k_address address;
-
-- if (!m68k_decompose_address (QImode, addr, true, &address))
-+ if (!m68k_decompose_address (QImode, addr, true, &address)) {
-+ debug_rtx(addr);
- gcc_unreachable ();
-+ }
-
- if (address.code == PRE_DEC)
- fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
-@@ -4719,7 +4721,7 @@ print_operand_address (FILE *file, rtx addr)
- /* (d16,PC) or (bd,PC,Xn) (with suppressed index register). */
- fputc ('(', file);
- output_addr_const (file, addr);
-- asm_fprintf (file, flag_pic == 1 ? ":w,%Rpc)" : ":l,%Rpc)");
-+ asm_fprintf (file, flag_pic == 1 || flag_pic == 3 ? ":w,%Rpc)" : ":l,%Rpc)");
- }
- else
- {
-@@ -5124,8 +5126,8 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
- /* Use the static chain register as a temporary (call-clobbered)
- GOT pointer for this function. We can use the static chain
- register because it isn't live on entry to the thunk. */
-- SET_REGNO (pic_offset_table_rtx, STATIC_CHAIN_REGNUM);
-- emit_insn (gen_load_got (pic_offset_table_rtx));
-+// SET_REGNO (pic_offset_table_rtx, STATIC_CHAIN_REGNUM);
-+// emit_insn (gen_load_got (pic_offset_table_rtx));
- }
- legitimize_pic_address (XEXP (mem, 0), Pmode, tmp);
- mem = replace_equiv_address (mem, tmp);
-
-From e807bcc3fe2a83cc3b617c78c7f81685e861b5d1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 12 Jan 2017 00:20:27 +0100
-Subject: [PATCH 006/303] @I
-
----
- gcc/config/m68k/amigaos.c | 0
- gcc/config/m68k/amigaos.h | 0
- gcc/config/m68k/amigaos.opt | 0
- 3 files changed, 0 insertions(+), 0 deletions(-)
- mode change 100644 => 100755 gcc/config/m68k/amigaos.c
- mode change 100644 => 100755 gcc/config/m68k/amigaos.h
- mode change 100644 => 100755 gcc/config/m68k/amigaos.opt
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-old mode 100644
-new mode 100755
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-old mode 100644
-new mode 100755
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-old mode 100644
-new mode 100755
-
-From 79e34a64428598cfb90bdf9f67aa32ad8c02effb Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 12 Jan 2017 00:21:21 +0100
-Subject: [PATCH 007/303] Revert "@I"
-
-This reverts commit e807bcc3fe2a83cc3b617c78c7f81685e861b5d1.
----
- gcc/config/m68k/amigaos.c | 0
- gcc/config/m68k/amigaos.h | 0
- gcc/config/m68k/amigaos.opt | 0
- 3 files changed, 0 insertions(+), 0 deletions(-)
- mode change 100755 => 100644 gcc/config/m68k/amigaos.c
- mode change 100755 => 100644 gcc/config/m68k/amigaos.h
- mode change 100755 => 100644 gcc/config/m68k/amigaos.opt
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-old mode 100755
-new mode 100644
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-old mode 100755
-new mode 100644
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-old mode 100755
-new mode 100644
-
-From 010fd69732e88d124686e46202f7a26bc9fa77ec Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 12 Jan 2017 15:13:10 +0100
-Subject: [PATCH 008/303] @B fix endless option parsing loop
-
----
- gcc/config/m68k/amigaos.opt | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 4298bc90abe1..f933fe29b98b 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -12,9 +12,9 @@ Target RejectNegative
- small code model
-
- fbaserel
--Target Common Report Var(flag_pic,3) Negative(fpie) Init(-1)
-+Target Common Report Var(flag_pic,3) Init(-1)
- Backward compatibility, use -fpic now
-
- fbaserel32
--Target Common Report Var(flag_pic,4) Negative(fPIE) Init(-1)
-+Target Common Report Var(flag_pic,4) Init(-1)
- Backward compatibility, use -fPIC now
-\ No newline at end of file
-
-From c8b17fa2d8719ce6efc9535408966cd7ce87e2b8 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 31 Jan 2017 20:42:38 +0100
-Subject: [PATCH 009/303] @N re-added old target options, @R -fbaserel seems to
- work
-
----
- gcc/config/m68k/amigaos.c | 7 +-
- gcc/config/m68k/amigaos.opt | 20 ++-
- gcc/config/m68k/m68k.c | 30 +++--
- gcc/config/m68k/m68kamigaos.h | 283 ++++++++++++++++++++++++++++++++----------
- 4 files changed, 257 insertions(+), 83 deletions(-)
- mode change 100755 => 100644 gcc/config/m68k/m68kamigaos.h
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 8727c7184812..19b0f5b4cc82 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -41,6 +41,8 @@ Boston, MA 02111-1307, USA. */
- #include "config/m68k/amigaos.h"
-
-
-+//int amiga_declare_object;
++ for (int pos = start; pos >= 0; --pos)
++ {
++ insn_info & pp = infos[pos];
++ rtx_insn * insn = pp.get_insn ();
+
- #if 0
- static int amigaos_put_in_text (tree);
- static rtx gen_stack_management_call (rtx, rtx, const char *);
-@@ -776,6 +778,9 @@ amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
- extern void
- amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
- {
-- fprintf (asm_out_file, "\t.section\t%s\n", name);
-+ if (0 == strncmp(".text", name, 5))
-+ name = ".text";
-+// fprintf (asm_out_file, "\t.section\t%s\n", name);
-+ fprintf (asm_out_file, "\t%s\n", name);
- }
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index f933fe29b98b..29a3688470d0 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -12,9 +12,21 @@ Target RejectNegative
- small code model
-
- fbaserel
--Target Common Report Var(flag_pic,3) Init(-1)
--Backward compatibility, use -fpic now
-+Target Common Report Var(flag_mybaserel,1)
-+data is adressed relativ to a4
-
- fbaserel32
--Target Common Report Var(flag_pic,4) Init(-1)
--Backward compatibility, use -fPIC now
-\ No newline at end of file
-+Target Common Report Var(flag_mybaserel,2)
-+data is adressed relativ to a4 with 32 bit offsets
++ // do not run into previous epilogue
++ if (pp.in_proepi () >= IN_EPILOGUE && !proepi)
++ break;
+
-+resident
-+Target Common Report Var(flag_mybaserel,1)
-+data is adressed relativ to a4, linked as resident
++ proepi = pp.in_proepi ();
+
-+resident32
-+Target Common Report Var(flag_mybaserel,2)
-+data is adressed relativ to a4 with 32 bit offsets, linked as resident
++ /* no new information -> break. */
++ if (pos != start && pp.is_visited () && !JUMP_P(insn) && pp.contains (ii))
++ break;
+
-+mcrt=
-+Target RejectNegative Var(amigaos_crt) Joined
-+Specify startup binary
-\ No newline at end of file
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index ce28681c1dc9..387f0c1b9e02 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -1139,9 +1139,9 @@ m68k_expand_prologue (void)
- current_frame.reg_mask, true, true));
- }
-
--// if (!TARGET_SEP_DATA
--// && crtl->uses_pic_offset_table)
--// emit_insn (gen_load_got (pic_offset_table_rtx));
-+ if (!TARGET_SEP_DATA
-+ && crtl->uses_pic_offset_table)
-+ emit_insn (gen_load_got (pic_offset_table_rtx));
- }
-
- /* Return true if a simple (return) instruction is sufficient for this
-@@ -4496,7 +4496,10 @@ print_operand (FILE *file, rtx op, int letter)
- && !(GET_CODE (XEXP (op, 0)) == CONST_INT
- && INTVAL (XEXP (op, 0)) < 0x8000
- && INTVAL (XEXP (op, 0)) >= -0x8000))
-- fprintf (file, MOTOROLA ? ".l" : ":l");
-+#ifdef TARGET_AMIGA
-+ if (!flag_mybaserel)
-+#endif
-+ fprintf (file, MOTOROLA ? ".l" : ":l");
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
- {
-@@ -4693,10 +4696,8 @@ print_operand_address (FILE *file, rtx addr)
- {
- struct m68k_address address;
-
-- if (!m68k_decompose_address (QImode, addr, true, &address)) {
-- debug_rtx(addr);
-+ if (!m68k_decompose_address (QImode, addr, true, &address))
- gcc_unreachable ();
-- }
-
- if (address.code == PRE_DEC)
- fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
-@@ -4721,7 +4722,7 @@ print_operand_address (FILE *file, rtx addr)
- /* (d16,PC) or (bd,PC,Xn) (with suppressed index register). */
- fputc ('(', file);
- output_addr_const (file, addr);
-- asm_fprintf (file, flag_pic == 1 || flag_pic == 3 ? ":w,%Rpc)" : ":l,%Rpc)");
-+ asm_fprintf (file, flag_pic == 1 ? ":w,%Rpc)" : ":l,%Rpc)");
- }
- else
- {
-@@ -4738,6 +4739,15 @@ print_operand_address (FILE *file, rtx addr)
- }
- else
- output_addr_const (file, addr);
++ ii.clear_hard_def ();
++ ii.merge (pp);
+
-+ if (!RTX_FLAG (addr, frame_related))
++ if (LABEL_P(insn))
+ {
-+// debug_rtx(addr);
-+ if (flag_mybaserel == 1)
-+ asm_fprintf (file, ".w(a4)");
-+ else if (flag_mybaserel == 2)
-+ asm_fprintf (file, "(a4)");
-+ }
- }
- }
- else
-@@ -5126,8 +5136,8 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
- /* Use the static chain register as a temporary (call-clobbered)
- GOT pointer for this function. We can use the static chain
- register because it isn't live on entry to the thunk. */
--// SET_REGNO (pic_offset_table_rtx, STATIC_CHAIN_REGNUM);
--// emit_insn (gen_load_got (pic_offset_table_rtx));
-+ SET_REGNO (pic_offset_table_rtx, STATIC_CHAIN_REGNUM);
-+ emit_insn (gen_load_got (pic_offset_table_rtx));
- }
- legitimize_pic_address (XEXP (mem, 0), Pmode, tmp);
- mem = replace_equiv_address (mem, tmp);
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-old mode 100755
-new mode 100644
-index 0ce599138c7d..df0ce5b52ede
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -25,6 +25,8 @@ along with GCC; see the file COPYING3. If not see
- #define TARGET_AMIGA 1
- #endif
-
-+#define HAS_INIT_SECTION
++ /* work on all jumps referring to that label. */
++ l2j_iterator i = label2jump.find (insn->u2.insn_uid);
+
- #ifndef SWBEG_ASM_OP
- #define SWBEG_ASM_OP "\t.swbeg\t"
- #endif
-@@ -88,6 +90,28 @@ do { \
- fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, 1 << (LOG)); \
- } while (0)
-
-+#if 0
-+extern int amiga_declare_object;
++ /* no jump to here -> mark all registers as hard regs.
++ * This label is maybe used in an exception handler.
++ * Marking as hard also avoids stack frame removal.
++ */
++ if (i == label2jump.end ())
++ infos[pos + 1].make_hard ();
++ else
++ for (l2j_iterator k = i; i != label2jump.end () && i->first == k->first; ++i)
++ {
++ i2i_iterator j = insn2info.find (i->second);
++ if (j != insn2info.end ())
++ {
++ unsigned index = j->second->get_index ();
++ insn_info & jj = infos[index];
++ if (!jj.is_visited () || !jj.contains (ii))
++ {
++ jj.updateWith (ii);
++ todo.insert (index);
++ }
++ }
++ }
+
-+#define ASM_DECLARE_OBJECT_NAME(FILE,NAME,DECL) \
-+if (!DECL_INITIAL (DECL) || \
-+ initializer_zerop (DECL_INITIAL (decl))) \
-+ { \
-+ amiga_declare_object = 1; \
-+ fprintf ((FILE), ".comm\t%s,", NAME); \
-+ } \
-+else \
-+ASM_OUTPUT_LABEL (FILE, NAME)
++ if (pos == start)
++ pp.mark_visited ();
+
-+#undef ASM_OUTPUT_SKIP
-+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
-+if (amiga_declare_object) \
-+ fprintf (FILE, "%u\n", (int)(SIZE)); \
-+else \
-+ fprintf (FILE, "\t.skip %u\n", (int)(SIZE)); \
-+amiga_declare_object = 0
-+#endif
++ /* check previous insn for jump */
++ if (pos > 0 && infos[pos - 1].is_jump ())
++ {
++ rtx_insn * prev = infos[pos - 1].get_insn ();
++ rtx set = single_set (prev);
++ /* unconditional? -> break! */
++ if (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) != IF_THEN_ELSE)
++ break;
++ }
+
- /* Register in which address to store a structure value is passed to a
- function. The default in m68k.h is a1. For m68k/SVR4 it is a0. */
-
-@@ -145,14 +169,8 @@ do { \
- fprintf ((FILE), "%s&%d\n", SWBEG_ASM_OP, XVECLEN (PATTERN (TABLE), 1));
- /* end of stuff from m68kv4.h */
-
--#undef ENDFILE_SPEC
--#define ENDFILE_SPEC "crtend.o%s"
--
--#undef STARTFILE_SPEC
--#define STARTFILE_SPEC "crtbegin.o%s"
--
- #ifndef BSS_SECTION_ASM_OP
--#define BSS_SECTION_ASM_OP "\t.section\t.bss"
-+#define BSS_SECTION_ASM_OP "\t.bss"
- #endif
-
- #ifndef ASM_OUTPUT_ALIGNED_BSS
-@@ -168,8 +186,6 @@ do { \
- provided for compatibility reasons.
- When creating shared libraries, use different 'errno'. */
-
--
--
- #undef TARGET_OS_CPP_BUILTINS
- #define TARGET_OS_CPP_BUILTINS() \
- do \
-@@ -178,8 +194,8 @@ do { \
- 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 ("__regargs=__attribute__((regparm))"); \
-+ builtin_define ("__stdargs=__attribute__((stkparm))"); \
- builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \
- builtin_define_std ("amiga"); \
- builtin_define_std ("amigaos"); \
-@@ -195,6 +211,11 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
-
- #endif
-
-+/* 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))
++ continue;
++ }
+
- /* Inform the program which CPU we compile for. */
-
- //#undef TARGET_CPU_CPP_BUILTINS
-@@ -229,14 +250,27 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- } \
- while (0)
- */
++ pp.mark_visited ();
+
-+/* When creating shared libraries, use different 'errno'. */
-+#define CPP_IXEMUL_SPEC \
-+ "%{!ansi:-Dixemul} -D__ixemul__ -D__ixemul " \
-+ "%{malways-restore-a4:-Derrno=(*ixemul_errno)} " \
-+ "%{mrestore-a4:-Derrno=(*ixemul_errno)}"
-+#define CPP_LIBNIX_SPEC \
-+ "-isystem %(sdk_root)libnix/include " \
-+ "%{!ansi:-Dlibnix} -D__libnix__ -D__libnix"
-+#define CPP_CLIB2_SPEC \
-+ "-isystem %(sdk_root)clib2/include " \
-+ "%{!ansi:-DCLIB2} -D__CLIB2__ -D__CLIB2"
++ rtx pattern = PATTERN (insn);
++ insn_info use (insn);
++ use.scan ();
++ if (locka4 && (use.get_myuse () & (1 << PIC_REG)))
++ use.mark_hard (PIC_REG);
+
- /* 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__} " \
-+#define CPP_SPEC \
-+ "%{m68881:-D__HAVE_68881__} " \
- "%{!ansi:" \
- "%{m68020:-Dmc68020} " \
- "%{mc68020:-Dmc68020} " \
-@@ -252,16 +286,10 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{m68030:-D__mc68030__ -D__mc68030} " \
- "%{m68040:-D__mc68040__ -D__mc68040} " \
- "%{m68060:-D__mc68060__ -D__mc68060} " \
-- "%{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}"
-+ "%{noixemul:%(cpp_libnix)} " \
-+ "%{mcrt=nix*:%(cpp_libnix)} " \
-+ "%{mcrt=ixemul:%(cpp_ixemul)} " \
-+ "%{mcrt=clib2:%(cpp_clib2)}"
-
- /* Various -m flags require special flags to the assembler. */
-
-@@ -280,48 +308,56 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- #define ASM_CPU_DEFAULT_SPEC \
- "%{!m680*:%{!mc680*:-m68040}}"
-
--/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD
-- compatible debug hunk.
-- Also, pass appropriate linker flavours depending on user-supplied
-- commandline options. */
--
--#define LINK_SPEC \
-- "%{noixemul:-fl libnix} " \
-- "%{resident*:-amiga-datadata-reloc} " \
-- "%{resident|fbaserel:-m amiga_bss -fl libb} " \
-- "%{resident32|fbaserel32:-m amiga_bss -fl libb32} " \
-- "%{g:-amiga-debug-hunk} " \
-- "%(link_cpu)"
--
--#define LINK_CPU_SPEC \
-- "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \
-- "%{m68881:-fl libm881}"
--
- /* Choose the right startup file, depending on whether we use base relative
- code, base relative code with automatic relocation (-resident), their
- 32-bit versions, libnix, profiling or plain crt0.o. */
-
--#undef STARTFILE_SPEC
--#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 STARTFILE_IXEMUL_SPEC \
-+ "%{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}}}}}}"
-+#define STARTFILE_LIBNIX_SPEC \
-+ "%(sdk_root)lib/libnix/" \
-+ "%{ramiga-*:" \
-+ "%{ramiga-lib:libinit.o%s}" \
-+ "%{ramiga-libr:libinitr.o%s}" \
-+ "%{ramiga-dev:devinit.o%s}}" \
-+ "%{!ramiga-*:" \
-+ "%{resident:nrcrt0.o%s}" \
-+ "%{!resident:" \
-+ "%{fbaserel:nbcrt0.o%s}" \
-+ "%{!fbaserel:ncrt0.o%s}}}"
-+#define STARTFILE_CLIB2_SPEC \
-+ "%(sdk_root)clib2/lib/" \
-+ "%{resident32:nr32crt0.o%s}" \
-+ "%{!resident32:" \
-+ "%{fbaserel32:nb32crt0.o%s}" \
-+ "%{!fbaserel32:" \
-+ "%{resident:nrcrt0.o%s}" \
-+ "%{!resident:" \
-+ "%{fbaserel:nbcrt0.o%s}" \
-+ "%{!fbaserel:ncrt0.o%s}}}}"
-
--#undef ENDFILE_SPEC
--#define ENDFILE_SPEC \
-- "%{noixemul:-lstubs}"
-+#undef STARTFILE_SPEC
-+#define STARTFILE_SPEC \
-+ "%{noixemul:%(startfile_libnix)} " \
-+ "%{mcrt=nix*:%(startfile_libnix)} " \
-+ "%{mcrt=ixemul:%(startfile_ixemul)} " \
-+ "%{mcrt=clib2:%(startfile_clib2)}"
-
--/* 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))
-+#define ENDFILE_IXEMUL_SPEC ""
-+#define ENDFILE_LIBNIX_SPEC "-lstubs"
-+#define ENDFILE_CLIB2_SPEC ""
++ /* do not mark a node as visited, if it's in epilogue and not yet visited. */
++ if (CALL_P(insn) || JUMP_P(insn))
++ {
++ if (pos != start && ii.in_proepi ())
++ {
++ su_iterator k = scan_starts.find (pos);
++ if (k != scan_starts.end ())
++ {
++ pp.clear_visited ();
++ break;
++ }
++ }
++ }
++ else if (GET_CODE (pattern) == USE || GET_CODE (pattern) == CLOBBER)
++ {
++ use.make_clobber ();
++ }
++ else if (single_set (insn) == 0)
++ use.make_hard ();
++ else
++ /* if not cc0 defined check for mod. */
++ if (!use.is_def (FIRST_PSEUDO_REGISTER))
++ {
++ CC_STATUS_INIT;
++ NOTICE_UPDATE_CC(PATTERN (insn), insn);
++ if (cc_status.value1 || cc_status.value2)
++ use.mark_def (FIRST_PSEUDO_REGISTER);
++ }
+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{noixemul:%(endfile_libnix)} " \
-+ "%{mcrt=nix*:%(endfile_libnix)} " \
-+ "%{mcrt=ixemul:%(endfile_ixemul)} " \
-+ "%{mcrt=clib2:%(endfile_clib2)}"
-
-
- /* Automatically search libamiga.a for AmigaOS specific functions. Note
-@@ -337,13 +373,106 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- 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. */
-
--#undef LIB_SPEC
--#define LIB_SPEC \
-- "%{!noixemul:" \
-- "%{p|pg:-lc_p}" \
-- "%{!p:%{!pg:-lc -lamiga -lc}}}" \
-- "%{noixemul:" \
-- "-lnixmain -lnix -lamiga %{mstackcheck|mstackextend:-lstack}}"
-+#define LIB_IXEMUL_SPEC \
-+ "%{!p:%{!pg:-lc -lamiga -lc}} " \
-+ "%{p:-lc_p} %{pg:-lc_p}"
-+#define LIB_LIBNIX_SPEC \
-+ "-lnixmain -lnix -lstubs " \
-+ "%{mcrt=*:-l%*} " \
-+ "%{!mcrt=*:-lnix20} " \
-+ "-lamiga " \
-+ "%{mstackcheck:-lstack} " \
-+ "%{mstackextend:-lstack}"
-+#define LIB_CLIB2_SPEC \
-+ "-lc -lamiga -ldebug " \
-+ "%{mstackcheck:-lstack} " \
-+ "%{mstackextend:-lstack}"
++ // TODO: use 2 bits for data regs, to indicate mode size
++// // also check mode size if < 4, it's also a use for data registers.
++// if (pp.get_dst_reg () && pp.get_dst_regno () < 8 && GET_MODE_SIZE(pp.get_mode()) < 4)
++// use.mark_use (pp.get_dst_regno ());
+
-+#define LIB_SPEC \
-+ "%{noixemul:%(lib_libnix)} " \
-+ "%{mcrt=nix*:%(lib_libnix)} " \
-+ "%{mcrt=ixemul:%(lib_ixemul)} " \
-+ "%{mcrt=clib2:%(lib_clib2)}"
++ /* mark not renameable in prologue/epilogue. */
++ if (pp.in_proepi () != IN_CODE)
++ use.make_hard ();
+
-+#define LIBGCC_IXEMUL_SPEC ""
-+#define LIBGCC_LIBNIX_SPEC "-lnix " \
-+ "%{mcrt=*:-l%*} " \
-+ "%{!mcrt=*:-lnix20}"
-+#define LIBGCC_CLIB2_SPEC "-lc"
-+//#define LIBGCC_SPEC "-lgcc "
-+#define LIBGCC_SPEC " " \
-+ "%{noixemul:%(libgcc_libnix)} " \
-+ "%{mcrt=nix*:%(libgcc_libnix)} " \
-+ "%{mcrt=ixemul:%(libgcc_ixemul)} " \
-+ "%{mcrt=clib2:%(libgcc_clib2)}"
++ ii.merge (use);
++ pp.update (ii);
++ ii.updateWith (use);
++ }
++ }
+
-+/* 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. */
++ /* fill the mask of general used regs. */
++ insn_info zz;
++ for (unsigned i = 0; i < infos.size (); ++i)
++ {
++ insn_info & ii = infos[i];
++ if (ii.in_proepi () != IN_PROLOGUE)
++ break;
+
-+#define LINK_IXEMUL_SPEC ""
-+#define LINK_LIBNIX_SPEC "-L%(sdk_root)libnix/lib -fl libnix"
-+#define LINK_CLIB2_SPEC "-L%(sdk_root)clib2/lib"
++ zz.or_use (ii);
++ }
+
-+/* 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. */
++ /* always allow a0/a1, d0/d1. */
++ usable_regs = zz.get_use () | 0x303;
++ if (flag_pic)
++ usable_regs &= ~(1 << PIC_REG);
+
-+#define LINK_SPEC \
-+ "%{noixemul:%(link_libnix)} " \
-+ "%{mcrt=nix*:%(link_libnix)} " \
-+ "%{mcrt=ixemul:%(link_ixemul)} " \
-+ "%{mcrt=clib2:%(link_clib2)} " \
-+ "%{fbaserel:%{!resident:-m amiga_bss -fl libb}} " \
-+ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb} " \
-+ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32}} " \
-+ "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32} " \
-+ "%{g:-amiga-debug-hunk} " \
-+ "%{m68020:-fl libm020} " \
-+ "%{mc68020:-fl libm020} " \
-+ "%{m68030:-fl libm020} " \
-+ "%{m68040:-fl libm020} " \
-+ "%{m68060:-fl libm020} " \
-+ "%{m68020-40:-fl libm020} " \
-+ "%{m68020-60:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
++ if (infos.size () && infos[0].is_use (FRAME_POINTER_REGNUM))
++ usable_regs &= ~(1 << FRAME_POINTER_REGNUM);
+
-+/* Translate '-resident' to '-fbaserel' (they differ in linking stage only).
-+ Don't put function addresses in registers for PC-relative code. */
++ usable_regs &= ~(1 << STACK_POINTER_REGNUM);
++}
+
-+#define CC1_SPEC \
-+ "%{resident:-fbaserel} " \
-+ "%{resident32:-fbaserel32} " \
-+ "%{msmall-code:-fno-function-cse}"
++enum AbortCodes
++{
++ E_OK, E_NO_JUMP_LABEL, E_JUMP_TABLE_MISMATCH, E_JUMP_GOTO_LABEL, E_SP_MISMATCH
++};
+
-+#define LINK_CPU_SPEC \
-+ "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
++/*
++ * Create a filtered view of insns - keep only those to work with.
++ */
++static unsigned
++update_insns ()
++{
++ rtx_insn *insn, *next;
++ unsigned result = 0;
++ rtx jump_table = 0;
+
-+/* [cahirwpz] A modified copy of LINK_COMMAND_SPEC from gcc/gcc.c file.
-+ Don't prepend libgcc.a to link libraries and make sure the options is
-+ at the end of command line. Otherwise linker chooses generic functions
-+ from libgcc.a instead AmigaOS-specific counterparts from libnix.a. */
++ clear ();
+
-+#define LINK_COMMAND_SPEC \
-+ "%{!fsyntax-only:" \
-+ "%{!c:" \
-+ "%{!M:" \
-+ "%{!MM:" \
-+ "%{!E:" \
-+ "%{!S:" \
-+ "%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} " \
-+ "%{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%S}}} " \
-+ "%{static:} %{L*} %D %o " \
-+ "%{!nostdlib:%{!nodefaultlibs:%L}} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \
-+ "%{!nostdlib:%{!nodefaultlibs:%G}} " \
-+ "%{T*} }}}}}} " \
++ enum proepis inproepilogue = IN_PROLOGUE;
++ /* create a vector with relevant insn. */
++ for (insn = get_insns (); insn; insn = next)
++ {
++ next = NEXT_INSN (insn);
+
++ if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
++ {
+
-
- /* This macro defines names of additional specifications to put in the specs
- that can be used in various specifications like CC1_SPEC. Its definition
-@@ -358,8 +487,26 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- #define EXTRA_SPECS \
- { "asm_cpu", ASM_CPU_SPEC }, \
- { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
-- { "link_cpu", LINK_CPU_SPEC }
--
-+ { "link_cpu", LINK_CPU_SPEC }, \
-+ {"sdk_root", TOOLDIR_BASE_PREFIX "m68k-amigaos/"}, \
-+ {"cpp_ixemul", CPP_IXEMUL_SPEC}, \
-+ {"cpp_libnix", CPP_LIBNIX_SPEC}, \
-+ {"cpp_clib2", CPP_CLIB2_SPEC}, \
-+ {"lib_ixemul", LIB_IXEMUL_SPEC}, \
-+ {"lib_libnix", LIB_LIBNIX_SPEC}, \
-+ {"lib_clib2", LIB_CLIB2_SPEC}, \
-+ {"link_ixemul", LINK_IXEMUL_SPEC}, \
-+ {"link_libnix", LINK_LIBNIX_SPEC}, \
-+ {"link_clib2", LINK_CLIB2_SPEC}, \
-+ {"startfile_ixemul", STARTFILE_IXEMUL_SPEC}, \
-+ {"startfile_libnix", STARTFILE_LIBNIX_SPEC}, \
-+ {"startfile_clib2", STARTFILE_CLIB2_SPEC}, \
-+ {"endfile_ixemul", ENDFILE_IXEMUL_SPEC}, \
-+ {"endfile_libnix", ENDFILE_LIBNIX_SPEC}, \
-+ {"endfile_clib2", ENDFILE_CLIB2_SPEC}, \
-+ {"libgcc_ixemul", LIBGCC_IXEMUL_SPEC}, \
-+ {"libgcc_libnix", LIBGCC_LIBNIX_SPEC}, \
-+ {"libgcc_clib2", LIBGCC_CLIB2_SPEC}
-
- /* begin-GG-local: dynamic libraries */
-
-
-From d1df1ebb0f08f356222c21b1744476eb881b3b0c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 1 Feb 2017 11:40:21 +0100
-Subject: [PATCH 010/303] @B mregparm was always enabled with 2 registers. Now
- it's off.
-
----
- gcc/config/m68k/amigaos.c | 30 ++++++++++++++++++------------
- gcc/config/m68k/amigaos.opt | 2 +-
- gcc/config/m68k/m68k.c | 11 ++++++-----
- 3 files changed, 25 insertions(+), 18 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 19b0f5b4cc82..e2dd5bab75f9 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -40,6 +40,12 @@ Boston, MA 02111-1307, USA. */
- #include "diagnostic-core.h"
- #include "config/m68k/amigaos.h"
-
-+//#define MYDEBUG 1
-+#ifdef MYDEBUG
-+#define DPRINTF(x) printf x; fflush(stdout);
-+#else
-+#define DPRINTF(x)
-+#endif
-
- //int amiga_declare_object;
-
-@@ -379,8 +385,8 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype)
- {
- struct amigaos_args * cum = &mycum;
- lastcum = cump;
-- cum->num_of_regs = amigaos_regparm;
--// printf("amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs); fflush(stdout);
-+ cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
-+ DPRINTF(("amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
-
- /* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
-@@ -396,7 +402,7 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype)
- else
- {
- tree ratree = lookup_attribute ("regparm", TYPE_ATTRIBUTES(fntype));
-- cum->num_of_regs = amigaos_regparm ?
-+ cum->num_of_regs = amigaos_regparm != 0 ?
- amigaos_regparm : AMIGAOS_DEFAULT_REGPARM;
- if (ratree)
- {
-@@ -456,7 +462,7 @@ amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree,
- CUMULATIVE_ARGS *cump = (CUMULATIVE_ARGS *) get_cumulative_args (cum_v);
- /* Update the data in CUM to advance over an argument. */
-
-- // printf("amigaos_function_arg_advance1 %p\r\n", cump); fflush(stdout);
-+ DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cump));
- if (cump != lastcum)
- return;
-
-@@ -490,7 +496,7 @@ static struct rtx_def *
- _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
- {
- struct amigaos_args * cum = &mycum;
-- // printf("m68k_function_arg numOfRegs=%p\r\n", cum);
-+ DPRINTF(("m68k_function_arg numOfRegs=%d\r\n", cum ? cum->num_of_regs : 0));
-
- if (cump != lastcum)
- return 0;
-@@ -550,7 +556,7 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
-
- if (cum->last_arg_reg != -1)
- {
-- // printf("-> gen_rtx_REG %d\r\n", cum->last_arg_reg);
-+ DPRINTF(("-> gen_rtx_REG %d\r\n", cum->last_arg_reg));
- return gen_rtx_REG (mode, cum->last_arg_reg);
- }
- }
-@@ -566,7 +572,7 @@ amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
- {
- struct amigaos_args * cum = &mycum;
-
-- // printf("amigaos_function_arg %p\r\n", cum_v.p); fflush(stdout);
-+ DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p));
-
- CUMULATIVE_ARGS *cump = (CUMULATIVE_ARGS *) get_cumulative_args (cum_v);
-
-@@ -598,7 +604,7 @@ amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
- int
- amigaos_comp_type_attributes (const_tree type1, const_tree type2)
- {
-- printf("amigaos_comp_type_attributes\n");
-+ DPRINTF(("amigaos_comp_type_attributes\n"));
- /* 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)
-@@ -688,7 +694,7 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args,
- {
- tree nnn = *node;
- do { // while (0);
--// printf("%p with treecode %d\n", node, TREE_CODE(nnn)); fflush(stdout);
-+ DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
- if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE
- || TREE_CODE (nnn) == METHOD_TYPE)
- {
-@@ -696,7 +702,7 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args,
- single class that should be used to pass arguments. */
- if (is_attribute_p ("regparm", name))
- {
--// printf ("regparm found\n"); fflush(stdout);
-+ DPRINTF(("regparm found\n"));
-
- if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
- {
-@@ -706,7 +712,7 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args,
- if (args && TREE_CODE (args) == TREE_LIST)
- {
- tree val = TREE_VALUE(args);
--// printf ("regparm with val: %d\n", TREE_CODE(val));
-+ DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
- if (TREE_CODE (val) == INTEGER_CST)
- {
- int no = TREE_INT_CST_LOW(val);
-@@ -765,7 +771,7 @@ bool
- amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
- int *total, bool speed)
- {
--// printf("outer: %d, opno: %d", outer_code, opno); fflush(stdout);
-+ DPRINTF(("outer: %d, opno: %d", outer_code, opno));
- // debug_rtx(x);
- bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
- *total *= 4;
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 29a3688470d0..212ab8e6efda 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -1,6 +1,6 @@
-
- mregparm=
--Target RejectNegative Var(amigaos_regparm) Joined UInteger
-+Target RejectNegative Var(amigaos_regparm) Joined UInteger Init(-1)
- Pass arguments through registers.
-
- noixemul
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 387f0c1b9e02..3ebc9020c4e0 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -166,7 +166,7 @@ static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
- static bool m68k_ok_for_sibcall_p (tree, tree);
- static bool m68k_tls_symbol_p (rtx);
- static rtx m68k_legitimize_address (rtx, rtx, machine_mode);
--#ifndef TARGET_AMIGAOS
-+#ifndef TARGET_AMIGA
- static
- #endif
- bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-@@ -2803,7 +2803,7 @@ const_int_cost (HOST_WIDE_INT i)
- }
- }
-
--#ifndef TARGET_AMIGAOS
-+#ifndef TARGET_AMIGA
- static
- #endif
- bool
-@@ -4544,9 +4544,10 @@ m68k_get_reloc_decoration (enum m68k_reloc reloc)
- switch (reloc)
- {
- case RELOC_GOT:
-- if (TARGET_AMIGAOS)
-- return "";
-- else if (MOTOROLA)
-+// if (TARGET_AMIGA)
-+// return "";
-+// else
-+ if (MOTOROLA)
- {
- if (flag_pic == 1 && TARGET_68020)
- return "@GOT.w";
-
-From 0a6678c57629151eaec736ce82fa69dcc4e08c53 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 9 Feb 2017 22:01:27 +0100
-Subject: [PATCH 011/303] @B select correct crt0 file with baserel32
-
----
- gcc/config/m68k/m68kamigaos.h | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index df0ce5b52ede..0650102861e8 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -329,7 +329,10 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{resident:nrcrt0.o%s}" \
- "%{!resident:" \
- "%{fbaserel:nbcrt0.o%s}" \
-- "%{!fbaserel:ncrt0.o%s}}}"
-+ "%{!fbaserel:" \
-+ "%{fbaserel32:nlbcrt0.o%s}" \
-+ "%{!fbaserel32:ncrt0.o%s}}}}"
-+
- #define STARTFILE_CLIB2_SPEC \
- "%(sdk_root)clib2/lib/" \
- "%{resident32:nr32crt0.o%s}" \
-@@ -430,6 +433,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32}} " \
- "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32} " \
- "%{g:-amiga-debug-hunk} " \
-+ "%{mcpu=68020:-fl libm020} " \
- "%{m68020:-fl libm020} " \
- "%{mc68020:-fl libm020} " \
- "%{m68030:-fl libm020} " \
-
-From 38ec4180a5c5d9d7a87725d347838f3b55f837fa Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 9 Feb 2017 22:02:40 +0100
-Subject: [PATCH 012/303] @B -m68881 is not longer enabled by default for
- -m68020
-
----
- gcc/config/m68k/m68k.c | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 3ebc9020c4e0..c67194fa292d 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -352,11 +352,21 @@ struct gcc_target targetm = TARGET_INITIALIZER;
- /* Base flags for 68k ISAs. */
- #define FL_FOR_isa_00 FL_ISA_68000
- #define FL_FOR_isa_10 (FL_FOR_isa_00 | FL_ISA_68010)
--/* FL_68881 controls the default setting of -m68881. gcc has traditionally
-+/* "FL_68881 controls the default setting of -m68881. gcc has traditionally
- generated 68881 code for 68020 and 68030 targets unless explicitly told
-- not to. */
-+ not to."
++ infos.push_back (insn_info (insn, inproepilogue));
++ insn_info & ii = infos[infos.size () - 1];
+
-+ This is not true at least for the AMIGA.
-+ gcc 2.93 does not set the 68881 flag.
++ if (JUMP_P(insn))
++ {
++ if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
++ {
++ if (ANY_RETURN_P(PATTERN (insn)))
++ ii.set_proepi (IN_EPILOGUE);
+
-+ */
-+#ifdef TARGET_AMIGA
-+#define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
-+ | FL_BITFIELD | FL_CAS)
-+#else
- #define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
- | FL_BITFIELD | FL_68881 | FL_CAS)
-+#endif
- #define FL_FOR_isa_40 (FL_FOR_isa_20 | FL_ISA_68040)
- #define FL_FOR_isa_cpu32 (FL_FOR_isa_10 | FL_ISA_68020)
-
-
-From 5d9da9f9a2d9fec32fba2b7b9f2326d1f1c4f1f0 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 9 Feb 2017 22:05:42 +0100
-Subject: [PATCH 013/303] @R added a hack to support multiline __asm("...")
- statements
-
----
- gcc/c/c-parser.c | 7 +++++++
- libcpp/lex.c | 23 ++++++++++++++++++++++-
- 2 files changed, 29 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
-index d8725b572b55..cde6fe0c1c59 100644
---- gcc/c/c-parser.c
-+++ gcc/c/c-parser.c
-@@ -3908,6 +3908,7 @@ c_parser_asm_string_literal (c_parser *parser)
- static tree
- c_parser_simple_asm_expr (c_parser *parser)
- {
-+ extern int in_assembler_directive;
- tree str;
- gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
- /* ??? Follow the C++ parser rather than using the
-@@ -3919,7 +3920,13 @@ c_parser_simple_asm_expr (c_parser *parser)
- parser->lex_untranslated_string = false;
- return NULL_TREE;
- }
++ scan_starts.insert (infos.size () - 1);
++ inproepilogue = IN_CODE;
++ rtx set = single_set (insn);
++ if (ANY_RETURN_P(PATTERN (insn))
++ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) != IF_THEN_ELSE))
++ continue;
++ }
+
-+ // SBF: set in_assembler_directive to enable multi-line strings. And yes, it's a HACK.
-+ in_assembler_directive = 1;
- str = c_parser_asm_string_literal (parser);
-+ // SBF: in_assembler_directive disabled
-+ in_assembler_directive = 0;
++ ii.mark_jump ();
++ if (jump_table)
++ {
++ if (XEXP(jump_table, 0) != insn)
++ {
++ if (be_very_verbose)
++ {
++ debug_rtx (insn);
++ debug_rtx (jump_table);
++ }
++ result = E_JUMP_TABLE_MISMATCH;
++ jump_table = 0;
++ continue;
++ }
+
- parser->lex_untranslated_string = false;
- if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
- {
-diff --git a/libcpp/lex.c b/libcpp/lex.c
-index e5a0397f3099..c2131adeb38e 100644
---- libcpp/lex.c
-+++ libcpp/lex.c
-@@ -64,6 +64,10 @@ static tokenrun *next_tokenrun (tokenrun *);
-
- static _cpp_buff *new_buff (size_t);
-
-+/*
-+ * SBF: This flag is set if an asm statement is parsed, to support multiline strings in __asm()
-+ */
-+int in_assembler_directive;
-
- /* Utility routine:
-
-@@ -1063,7 +1067,10 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
- else if (note->type == 0)
- /* Already processed in lex_raw_string. */;
- else
-- abort ();
-+ {
-+// abort ();
-+ printf("ups: note type=%d\n", note->type);
-+ }
- }
- }
-
-@@ -1875,6 +1882,20 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
- break;
- else if (c == '\n')
- {
-+ /*
-+ * SBF: allow multi-line strings
-+ * Ignore the line end and move to next line.
-+ * Only fail, if there is no next line
-+ */
-+ if (in_assembler_directive)
++ // -> jump_table_data
++ rtx table = PATTERN (XEXP(jump_table, 1));
++ if (GET_CODE(table) == ADDR_DIFF_VEC || GET_CODE(table) == ADDR_VEC)
++ {
++ int k = GET_CODE(table) == ADDR_DIFF_VEC;
++ for (int j = 0; j < XVECLEN(table, k); ++j)
++ {
++ rtx ref = XVECEXP(table, k, j);
++ if (!LABEL_REF_NONLOCAL_P(ref))
++ {
++ rtx label = XEXP(ref, 0);
++ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
++ ii.set_proepi (IN_EPILOGUE);
++ }
++ }
++ }
++ else
++ {
++ if (be_very_verbose)
++ {
++ debug_rtx (insn);
++ debug_rtx (jump_table);
++ }
++ result = E_JUMP_GOTO_LABEL;
++ jump_table = 0;
++ continue;
++ }
++ jump_table = 0;
++ }
++ else
++ {
++ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
++ if (!label)
++ {
++ if (be_very_verbose)
++ debug_rtx (insn);
++ result = E_NO_JUMP_LABEL;
++ continue;
++ }
++ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
++ }
++ }
++ else if (LABEL_P(insn))
+ {
-+ cpp_buffer *buffer = pfile->buffer;
-+ if (buffer->cur < buffer->rlimit)
-+ CPP_INCREMENT_LINE (pfile, 0);
-+ buffer->need_line = true;
-+ if (_cpp_get_fresh_line (pfile))
-+ continue;
++ ii.mark_label ();
++ jump_table = 0;
++ ii.set_proepi (inproepilogue = IN_CODE);
++ if (infos.size () > 1)
++ scan_starts.insert (infos.size () - 1);
+ }
- cur--;
- /* Unmatched quotes always yield undefined behavior, but
- greedy lexing means that what appears to be an unterminated
-
-From 6515b7470c3baf385a0dca132bc1c71acbcdda5f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 12 Feb 2017 12:40:37 +0100
-Subject: [PATCH 014/303] @R allow used registers inside of the clobber list
-
----
- gcc/cfgexpand.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
-index b612293b1a7a..4215ae90c63d 100644
---- gcc/cfgexpand.c
-+++ gcc/cfgexpand.c
-@@ -2732,6 +2732,10 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
- {
- /* Conflicts between asm-declared register variables and the clobber
- list are not allowed. */
-+ /*
-+ * SBF: Why?
-+ */
-+#ifndef TARGET_AMIGA
- tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs);
-
- if (overlap)
-@@ -2744,7 +2748,7 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
- DECL_REGISTER (overlap) = 0;
- return true;
- }
--
-+#endif
- return false;
- }
-
-@@ -3255,11 +3259,15 @@ expand_asm_stmt (gasm *stmt)
- if (reg_overlap_mentioned_p (clobbered_reg, output_rvec[k]))
- internal_error ("asm clobber conflict with output operand");
-
-+/**
-+ * SBF: Why?
-+ */
-+#ifndef TARGET_AMIGA
- for (unsigned k = 0; k < ninputs - ninout; ++k)
- if (reg_overlap_mentioned_p (clobbered_reg, input_rvec[k]))
- internal_error ("asm clobber conflict with input operand");
-+#endif
- }
--
- XVECEXP (body, 0, i++) = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
- }
-
-
-From 7de2f3e6f2786a6d5e789230227f9d7c5f3e2316 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 12 Feb 2017 12:41:09 +0100
-Subject: [PATCH 015/303] @B fix mixing struct/class for the same class.
-
----
- gcc/coretypes.h | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/gcc/coretypes.h b/gcc/coretypes.h
-index 12067fdf5348..f0f069f6afa2 100644
---- gcc/coretypes.h
-+++ gcc/coretypes.h
-@@ -52,9 +52,9 @@ typedef const struct bitmap_head *const_bitmap;
- struct simple_bitmap_def;
- typedef struct simple_bitmap_def *sbitmap;
- typedef const struct simple_bitmap_def *const_sbitmap;
--struct rtx_def;
--typedef struct rtx_def *rtx;
--typedef const struct rtx_def *const_rtx;
-+class rtx_def;
-+typedef class rtx_def *rtx;
-+typedef const class rtx_def *const_rtx;
-
- /* Subclasses of rtx_def, using indentation to show the class
- hierarchy, along with the relevant invariant.
-
-From bb99da7652edb584a7825632fdccf0db0d7080d4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 12 Feb 2017 12:42:09 +0100
-Subject: [PATCH 016/303] @B fixed - on an unsigned value, add cast to signed
-
----
- gcc/hwint.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/hwint.h b/gcc/hwint.h
-index 14740ccc939a..cd4a35c98f7b 100644
---- gcc/hwint.h
-+++ gcc/hwint.h
-@@ -294,7 +294,7 @@ abs_hwi (HOST_WIDE_INT x)
- inline unsigned HOST_WIDE_INT
- absu_hwi (HOST_WIDE_INT x)
- {
-- return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x;
-+ return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(signed HOST_WIDE_INT)x;
- }
-
- #endif /* ! GCC_HWINT_H */
-
-From e66d5a27e1e5257373172597fe9a699011b011d7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 12 Feb 2017 12:42:45 +0100
-Subject: [PATCH 017/303] @N add amiga target
-
----
- libgcc/config.host | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/libgcc/config.host b/libgcc/config.host
-index 124f2ceaefda..1849a2ec1980 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -811,6 +811,9 @@ m32r-*-linux*)
- m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
-+m68k-*-amiga*)
-+ tmake_file="$tmake_file m68k/t-floatlib"
-+ ;;
- m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
- ;;
-
-From c61b7d29f7f89cbec99115f6dfbb81b5e2967188 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 12 Feb 2017 12:44:25 +0100
-Subject: [PATCH 018/303] @B fix specs and linking paths issues
-
----
- gcc/config/m68k/amigaos.h | 9 ++++-----
- gcc/config/m68k/m68kamigaos.h | 41 ++++++++++++++++++++++-------------------
- gcc/gcc.c | 37 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 63 insertions(+), 24 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index fd89bb34352c..5f3348feb726 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -122,7 +122,6 @@ amiga_named_section (const char *name, unsigned int flags, tree decl);
- #undef TARGET_ASM_NAMED_SECTION
- #define TARGET_ASM_NAMED_SECTION amiga_named_section
-
--#if 0
- /* Various ABI issues. */
-
- /* This is (almost;-) BSD, so it wants DBX format. */
-@@ -183,12 +182,10 @@ amiga_named_section (const char *name, unsigned int flags, tree decl);
- //#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
-
- #undef WCHAR_TYPE
--#define WCHAR_TYPE "unsigned int"
-+#define WCHAR_TYPE "unsigned short"
-
- /* XXX: section support */
--#if 0
--
--
-+#if 0
- /* 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
-@@ -222,6 +219,8 @@ do \
- } \
- while (0)
-
-+#if 0
-+
- /* Baserel support. */
-
- /* Given that symbolic_operand(X), return TRUE if no special
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 0650102861e8..6ba2e6736b6a 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -257,10 +257,10 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{malways-restore-a4:-Derrno=(*ixemul_errno)} " \
- "%{mrestore-a4:-Derrno=(*ixemul_errno)}"
- #define CPP_LIBNIX_SPEC \
-- "-isystem %(sdk_root)libnix/include " \
-+ "-isystem %:sdk_root(libnix/include) " \
- "%{!ansi:-Dlibnix} -D__libnix__ -D__libnix"
- #define CPP_CLIB2_SPEC \
-- "-isystem %(sdk_root)clib2/include " \
-+ "-isystem %:sdk_root(clib2/include) " \
- "%{!ansi:-DCLIB2} -D__CLIB2__ -D__CLIB2"
-
- /* Define __HAVE_68881__ in preprocessor according to the -m flags.
-@@ -320,7 +320,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{!resident:%{!fbaserel:%{!resident32:%{!fbaserel32:" \
- "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}}}"
- #define STARTFILE_LIBNIX_SPEC \
-- "%(sdk_root)lib/libnix/" \
-+ "%:sdk_root(libnix/lib/libnix/ " \
- "%{ramiga-*:" \
- "%{ramiga-lib:libinit.o%s}" \
- "%{ramiga-libr:libinitr.o%s}" \
-@@ -331,10 +331,11 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{fbaserel:nbcrt0.o%s}" \
- "%{!fbaserel:" \
- "%{fbaserel32:nlbcrt0.o%s}" \
-- "%{!fbaserel32:ncrt0.o%s}}}}"
-+ "%{!fbaserel32:ncrt0.o%s}}}}" \
-+ ")"
-
- #define STARTFILE_CLIB2_SPEC \
-- "%(sdk_root)clib2/lib/" \
-+ "%:sdk_root(clib2/lib/ " \
- "%{resident32:nr32crt0.o%s}" \
- "%{!resident32:" \
- "%{fbaserel32:nb32crt0.o%s}" \
-@@ -342,7 +343,8 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{resident:nrcrt0.o%s}" \
- "%{!resident:" \
- "%{fbaserel:nbcrt0.o%s}" \
-- "%{!fbaserel:ncrt0.o%s}}}}"
-+ "%{!fbaserel:ncrt0.o%s}}}}" \
-+ ")"
-
- #undef STARTFILE_SPEC
- #define STARTFILE_SPEC \
-@@ -398,12 +400,11 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{mcrt=clib2:%(lib_clib2)}"
-
- #define LIBGCC_IXEMUL_SPEC ""
--#define LIBGCC_LIBNIX_SPEC "-lnix " \
-+#define LIBGCC_LIBNIX_SPEC "-lnix -fl libnix " \
- "%{mcrt=*:-l%*} " \
- "%{!mcrt=*:-lnix20}"
- #define LIBGCC_CLIB2_SPEC "-lc"
--//#define LIBGCC_SPEC "-lgcc "
--#define LIBGCC_SPEC " " \
-+#define LIBGCC_SPEC "-lgcc " \
- "%{noixemul:%(libgcc_libnix)} " \
- "%{mcrt=nix*:%(libgcc_libnix)} " \
- "%{mcrt=ixemul:%(libgcc_ixemul)} " \
-@@ -415,8 +416,8 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- commandline options. */
-
- #define LINK_IXEMUL_SPEC ""
--#define LINK_LIBNIX_SPEC "-L%(sdk_root)libnix/lib -fl libnix"
--#define LINK_CLIB2_SPEC "-L%(sdk_root)clib2/lib"
-+#define LINK_LIBNIX_SPEC "-L%:sdk_root(libnix/lib) -fl libnix"
-+#define LINK_CLIB2_SPEC "-L%:sdk_root(clib2/lib)"
-
- /* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD
- compatible debug hunk.
-@@ -428,10 +429,10 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{mcrt=nix*:%(link_libnix)} " \
- "%{mcrt=ixemul:%(link_ixemul)} " \
- "%{mcrt=clib2:%(link_clib2)} " \
-- "%{fbaserel:%{!resident:-m amiga_bss -fl libb}} " \
-- "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb} " \
-- "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32}} " \
-- "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32} " \
-+ "%{fbaserel:%{!resident:-m amiga_bss -fl libb %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}} " \
-+ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32 %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32 %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}} " \
- "%{g:-amiga-debug-hunk} " \
- "%{mcpu=68020:-fl libm020} " \
- "%{m68020:-fl libm020} " \
-@@ -476,7 +477,10 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{!nostdlib:%{!nodefaultlibs:%G}} " \
- "%{T*} }}}}}} " \
-
-+extern const char * amiga_m68k_prefix_func(int, const char **);
-
-+#define EXTRA_SPEC_FUNCTIONS \
-+ { "sdk_root", amiga_m68k_prefix_func },
-
- /* This macro defines names of additional specifications to put in the specs
- that can be used in various specifications like CC1_SPEC. Its definition
-@@ -489,10 +493,9 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- 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 }, \
-- {"sdk_root", TOOLDIR_BASE_PREFIX "m68k-amigaos/"}, \
-+ {"asm_cpu", ASM_CPU_SPEC }, \
-+ {"asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
-+ {"link_cpu", LINK_CPU_SPEC }, \
- {"cpp_ixemul", CPP_IXEMUL_SPEC}, \
- {"cpp_libnix", CPP_LIBNIX_SPEC}, \
- {"cpp_clib2", CPP_CLIB2_SPEC}, \
-diff --git a/gcc/gcc.c b/gcc/gcc.c
-index 0f042b0f12f7..479a912c7b3e 100644
---- gcc/gcc.c
-+++ gcc/gcc.c
-@@ -10075,3 +10075,40 @@ driver_get_configure_time_options (void (*cb) (const char *option,
- obstack_free (&obstack, NULL);
- n_switches = 0;
- }
-+
-+#ifdef TARGET_AMIGA
-+const char * amiga_m68k_prefix_func(int argc, const char ** argv) {
-+ char * p = 0;
-+ if (standard_libexec_prefix)
-+ {
-+ char * glp = concat(standard_libexec_prefix, "",0);
-+ p = strrchr(glp, '/');
-+ if (p)
-+ {
-+ *p = 0;
-+ p = strrchr(glp, '/');
-+ if (p)
++ else if (CALL_P(insn))
+ {
-+ *p = 0;
-+ p = strrchr(glp, '/');
-+ if (p)
++ if (insn->jump)
+ {
-+ p[1] = 0;
-+ p = concat(glp, "m68k-amigaos/", 0);
++ ii.set_proepi (IN_EPILOGUE);
++ ii.mark_jump ();
++ scan_starts.insert (infos.size () - 1);
++ }
++ ii.mark_call ();
++ if (inproepilogue)
++ {
++ scan_starts.insert (infos.size () - 1);
++ inproepilogue = IN_CODE;
+ }
+ }
-+ }
-+ free(glp);
-+ }
-+ if (!p)
-+ p = concat("../../../../", "", 0);
-+
-+ for (int i = 0; i < argc; ++i) {
-+ char * q = concat(p, argv[i], 0);
-+ free(p);
-+ p = q;
-+ }
-+// printf("amiga_m68k_prefix_func='%s'\n", p);
-+ return p;
-+}
-+#endif
-
-From 476bb08c1155ea1a630fb456301fe273f24caca7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 13 Feb 2017 18:47:13 +0100
-Subject: [PATCH 019/303] @B disable builtins which also disables
- tree-loop-distribute-patterns which causes an infinite recursion since e.g.
- in memset the pattern is recognized and memset is called...
-
----
- gcc/config/m68k/m68kamigaos.h | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 6ba2e6736b6a..a0ab3f1a91da 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -576,3 +576,5 @@ amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
- #undef FIXED_INCLUDE_DIR
- #define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../os-include"
-
-+// this disables tree_loop_distribute_patterns
-+#define C_COMMON_OVERRIDE_OPTIONS flag_no_builtin = 1
-
-From c1d1a53baaa94d5560d8e5d9daa749fb8b773b3a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 16 Feb 2017 12:20:05 +0100
-Subject: [PATCH 020/303] @B fix includes for target AMIGA
-
----
- libstdc++-v3/include/c_global/cstdio | 2 ++
- libstdc++-v3/include/tr1/cstdint | 1 +
- 2 files changed, 3 insertions(+)
-
-diff --git a/libstdc++-v3/include/c_global/cstdio b/libstdc++-v3/include/c_global/cstdio
-index 86d524f96a62..522d065d4dc6 100644
---- libstdc++-v3/include/c_global/cstdio
-+++ libstdc++-v3/include/c_global/cstdio
-@@ -149,7 +149,9 @@ namespace std
- #if _GLIBCXX_USE_C99_STDIO
-
- #undef snprintf
-+#ifndef AMIGA
- #undef vfscanf
-+#endif
- #undef vscanf
- #undef vsnprintf
- #undef vsscanf
-diff --git a/libstdc++-v3/include/tr1/cstdint b/libstdc++-v3/include/tr1/cstdint
-index 7304d9008413..cdb8b704f0bb 100644
---- libstdc++-v3/include/tr1/cstdint
-+++ libstdc++-v3/include/tr1/cstdint
-@@ -31,6 +31,7 @@
-
- #pragma GCC system_header
-
-+#include <stdint.h>
- #include <bits/c++config.h>
-
- // For 8.22.1/1 (see C99, Notes 219, 220, 222)
-
-From 8a098e5a7bb1c14c1afa7946dce4416596418e8a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 16 Feb 2017 13:48:01 +0100
-Subject: [PATCH 021/303] @B fix header only for AMIGA
-
----
- libstdc++-v3/include/tr1/cstdint | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/libstdc++-v3/include/tr1/cstdint b/libstdc++-v3/include/tr1/cstdint
-index cdb8b704f0bb..7d6ab77ce17a 100644
---- libstdc++-v3/include/tr1/cstdint
-+++ libstdc++-v3/include/tr1/cstdint
-@@ -30,8 +30,9 @@
- #define _GLIBCXX_TR1_CSTDINT 1
-
- #pragma GCC system_header
--
-+#ifdef AMIGA
- #include <stdint.h>
-+#endif
- #include <bits/c++config.h>
-
- // For 8.22.1/1 (see C99, Notes 219, 220, 222)
-
-From a3e959953b7386e1576961fb4666f704b2edac7f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 18 Feb 2017 20:19:06 +0100
-Subject: [PATCH 022/303] @V version resports now 6.3.1a instead of 6.3.1
-
----
- gcc/BASE-VER | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/BASE-VER b/gcc/BASE-VER
-index dc0208aba8e4..b557a4031409 100644
---- gcc/BASE-VER
-+++ gcc/BASE-VER
-@@ -1 +1 @@
--6.3.1
-+6.3.1a
-
-From 708b7bc6002cf54e04d7f67e3fdb6627aead7714 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 19 Feb 2017 20:24:20 +0100
-Subject: [PATCH 023/303] @B fix __regargs, __stdargs plus register
- distribution
-
----
- gcc/config/m68k/amigaos-protos.h | 4 ++--
- gcc/config/m68k/amigaos.c | 19 +++++++++++--------
- gcc/config/m68k/amigaos.h | 2 ++
- gcc/config/m68k/m68kamigaos.h | 4 ++--
- 4 files changed, 17 insertions(+), 12 deletions(-)
- mode change 100755 => 100644 gcc/config/m68k/amigaos-protos.h
-
-diff --git a/gcc/config/m68k/amigaos-protos.h b/gcc/config/m68k/amigaos-protos.h
-old mode 100755
-new mode 100644
-index 66b553ab568f..97733002f4f9
---- gcc/config/m68k/amigaos-protos.h
-+++ gcc/config/m68k/amigaos-protos.h
-@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
- #undef TARGET_AMIGAOS
- #define TARGET_AMIGAOS 1
-
--extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree);
-+extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree, tree);
-
- /* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
-@@ -32,7 +32,7 @@ extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree);
-
- #undef INIT_CUMULATIVE_ARGS
- #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
-- (amigaos_init_cumulative_args(&(CUM), (FNTYPE)))
-+ (amigaos_init_cumulative_args(&(CUM), (FNTYPE), (INDIRECT)))
-
-
- extern int amigaos_restore_a4 (void);
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index e2dd5bab75f9..ad4bb9130cd5 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -381,7 +381,7 @@ static CUMULATIVE_ARGS * lastcum;
- For a library call, FNTYPE is 0. */
-
- void
--amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype)
-+amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- {
- struct amigaos_args * cum = &mycum;
- lastcum = cump;
-@@ -397,11 +397,12 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype)
-
- if (fntype)
- {
-- if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(fntype)))
-- cum->num_of_regs = 0;
-+ tree attrs = DECL_ATTRIBUTES(decl);
-+ if (lookup_attribute ("stkparm", attrs))
-+ cum->num_of_regs = 0;
- else
- {
-- tree ratree = lookup_attribute ("regparm", TYPE_ATTRIBUTES(fntype));
-+ tree ratree = lookup_attribute ("regparm", attrs);
- cum->num_of_regs = amigaos_regparm != 0 ?
- amigaos_regparm : AMIGAOS_DEFAULT_REGPARM;
- if (ratree)
-@@ -530,11 +531,11 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
- long mask;
-
- look_for_reg: mask = 1 << regbegin;
-- for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1)
-+ for (reg = 0; reg < AMIGAOS_MAX_REGPARM; reg++, mask <<= 1)
- if (!(cum->regs_already_used & mask))
- {
- int end;
-- for (end = reg; end < cum->num_of_regs && end < reg + len;
-+ for (end = reg; end < AMIGAOS_MAX_REGPARM && end < reg + len;
- end++, mask <<= 1)
- if (cum->regs_already_used & mask)
- break;
-@@ -546,8 +547,9 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
- }
- }
-
-- if (reg == cum->num_of_regs && altregbegin != -1)
-+ if (reg == AMIGAOS_MAX_REGPARM && altregbegin != -1)
- {
-+ DPRINTF(("look for alt reg\n"));
- regbegin = altregbegin;
- altregbegin = -1;
- goto look_for_reg;
-@@ -556,6 +558,7 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
-
- if (cum->last_arg_reg != -1)
- {
-+ --cum->num_of_regs;
- DPRINTF(("-> gen_rtx_REG %d\r\n", cum->last_arg_reg));
- return gen_rtx_REG (mode, cum->last_arg_reg);
- }
-@@ -771,7 +774,7 @@ bool
- amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
- int *total, bool speed)
- {
-- DPRINTF(("outer: %d, opno: %d", outer_code, opno));
-+// DPRINTF(("outer: %d, opno: %d", outer_code, opno));
- // debug_rtx(x);
- bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
- *total *= 4;
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 5f3348feb726..71a978e6df97 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -481,6 +481,8 @@ while (0)
- affects_type_identity } */
- #define SUBTARGET_ATTRIBUTES \
- { "regparm", 1, 1, true, false, false, amigaos_handle_type_attribute,\
-+ false }, \
-+ { "stkparm", 0, 0, true, false, false, amigaos_handle_type_attribute,\
- false },
-
- #define GOT_SYMBOL_NAME ""
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index a0ab3f1a91da..539d5f0bf934 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -194,8 +194,8 @@ amiga_declare_object = 0
- 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 ("__regargs=__attribute__((__regparm__))"); \
-+ builtin_define ("__stdargs=__attribute__((__stkparm__))"); \
- builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \
- builtin_define_std ("amiga"); \
- builtin_define_std ("amigaos"); \
-
-From e9ccb451229b09a1fdb64eb125d3ac0c733c5e9e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 20 Feb 2017 08:32:06 +0100
-Subject: [PATCH 024/303] @B do not append (a4) to function references.
-
----
- gcc/config/m68k/m68k.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index c67194fa292d..bd76c766a735 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -4751,7 +4751,7 @@ print_operand_address (FILE *file, rtx addr)
- else
- output_addr_const (file, addr);
-
-- if (!RTX_FLAG (addr, frame_related))
-+ if (!RTX_FLAG (addr, frame_related) && !SYMBOL_REF_FUNCTION_P(addr))
- {
- // debug_rtx(addr);
- if (flag_mybaserel == 1)
-
-From 40f1afb4c03c2bb79e86c5fb8fa2e7daa45d8600 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 20 Feb 2017 08:35:34 +0100
-Subject: [PATCH 025/303] @B enable reg-rename in O2+ and fix it.
-
----
- gcc/regrename.c | 5 +++--
- gcc/toplev.c | 2 +-
- 2 files changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index 9643f328ea3e..9816d3eaf5d2 100644
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -406,8 +406,9 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
-
- /* In the first pass, we force the renaming of registers that
- don't belong to PREFERRED_CLASS to registers that do, even
-- though the latters were used not very long ago. */
-- if ((pass == 0
-+ though the latters were used not very long ago.
-+ Also use a register if no best_new_reg was found till now */
-+ if (((pass == 0 || !has_preferred_class)
- && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
- best_new_reg))
- || tick[best_new_reg] > tick[new_reg])
-diff --git a/gcc/toplev.c b/gcc/toplev.c
-index 8979d2634260..96d17ee1cccc 100644
---- gcc/toplev.c
-+++ gcc/toplev.c
-@@ -1299,7 +1299,7 @@ process_options (void)
- flag_web = flag_unroll_loops || flag_peel_loops;
-
- if (flag_rename_registers == AUTODETECT_VALUE)
-- flag_rename_registers = flag_unroll_loops || flag_peel_loops;
-+ flag_rename_registers = flag_unroll_loops || flag_peel_loops || optimize >= 2;
-
- if (flag_non_call_exceptions)
- flag_asynchronous_unwind_tables = 1;
-
-From b980bd29d8cf05a2c6d6c947547b3f1e1c4cff23 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 20 Feb 2017 10:52:45 +0100
-Subject: [PATCH 026/303] @B fix npe in amigaos_init_cumulative_args
-
----
- gcc/config/m68k/amigaos.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index ad4bb9130cd5..c675bc8e01ed 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -395,7 +395,7 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- cum->last_arg_reg = -1;
- cum->regs_already_used = 0;
-
-- if (fntype)
-+ if (decl)
- {
- tree attrs = DECL_ATTRIBUTES(decl);
- if (lookup_attribute ("stkparm", attrs))
-
-From 215f15335dca293e65f47fde15a3d6486c551629 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Feb 2017 12:46:18 +0100
-Subject: [PATCH 027/303] @B -mregparm conforms now to the spec.
-
----
- gcc/config/m68k/amigaos.c | 22 +++++++++++-----------
- 1 file changed, 11 insertions(+), 11 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index c675bc8e01ed..916140bdc628 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -386,7 +386,7 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- struct amigaos_args * cum = &mycum;
- lastcum = cump;
- cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
-- DPRINTF(("amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
-+ DPRINTF(("0amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
-
- /* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
-@@ -451,6 +451,7 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- else
- /* Call to compiler-support function. */
- cum->formal_type = 0;
-+ DPRINTF(("1amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
- }
-
- /* Update the data in CUM to advance over an argument. */
-@@ -531,11 +532,11 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
- long mask;
-
- look_for_reg: mask = 1 << regbegin;
-- for (reg = 0; reg < AMIGAOS_MAX_REGPARM; reg++, mask <<= 1)
-+ for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1)
- if (!(cum->regs_already_used & mask))
- {
- int end;
-- for (end = reg; end < AMIGAOS_MAX_REGPARM && end < reg + len;
-+ for (end = reg; end < cum->num_of_regs && end < reg + len;
- end++, mask <<= 1)
- if (cum->regs_already_used & mask)
- break;
-@@ -547,18 +548,17 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
- }
- }
-
-- if (reg == AMIGAOS_MAX_REGPARM && altregbegin != -1)
-- {
-- DPRINTF(("look for alt reg\n"));
-- regbegin = altregbegin;
-- altregbegin = -1;
-- goto look_for_reg;
-- }
-+// if (reg == AMIGAOS_MAX_REGPARM && altregbegin != -1)
-+// {
-+// DPRINTF(("look for alt reg\n"));
-+// regbegin = altregbegin;
-+// altregbegin = -1;
-+// goto look_for_reg;
-+// }
- }
-
- if (cum->last_arg_reg != -1)
- {
-- --cum->num_of_regs;
- DPRINTF(("-> gen_rtx_REG %d\r\n", cum->last_arg_reg));
- return gen_rtx_REG (mode, cum->last_arg_reg);
- }
-
-From 419b54e138b5322b468189fbf9e234f6315b0914 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Feb 2017 12:47:40 +0100
-Subject: [PATCH 028/303] @B if -fbaserel32 -m68020 (or better) must be present
- too
-
----
- gcc/config/m68k/amigaos.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 71a978e6df97..afc2c6563143 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -470,7 +470,7 @@ extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
- #define SUBTARGET_OVERRIDE_OPTIONS \
- do \
- { \
-- if (!TARGET_68020 && flag_pic==2) \
-+ if (!TARGET_68020 && flag_mybaserel==2) \
- error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \
- if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
- error ("-mregparm=x with 1 <= x <= %d\n", AMIGAOS_MAX_REGPARM); \
-
-From f76ce97a5f8b9542814e5700e9d728ede215749d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Feb 2017 12:48:23 +0100
-Subject: [PATCH 029/303] @I -msmall-code sets now flag_smallcode
-
----
- gcc/config/m68k/amigaos.opt | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 212ab8e6efda..1faa3f2eeb26 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -8,7 +8,7 @@ Target RejectNegative
- Do not use ixemul.library - use libnix instead to link
-
- msmall-code
--Target RejectNegative
-+Target RejectNegative Var(flag_smallcode,1)
- small code model
-
- fbaserel
-
-From d08bd9d2a479285104f394f70be45e5f77dfa419 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Feb 2017 12:50:51 +0100
-Subject: [PATCH 030/303] @B fix baserel(32): use a4 only if common or bss is
- referenced @N support -msmall-code
-
----
- gcc/config/m68k/m68k.c | 36 ++++++++++++++++++++++++++++++------
- 1 file changed, 30 insertions(+), 6 deletions(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index bd76c766a735..b6ef99024ea6 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -4751,14 +4751,38 @@ print_operand_address (FILE *file, rtx addr)
- else
- output_addr_const (file, addr);
-
-- if (!RTX_FLAG (addr, frame_related) && !SYMBOL_REF_FUNCTION_P(addr))
-+#ifdef TARGET_AMIGA
-+ if (SYMBOL_REF_FUNCTION_P(addr))
- {
--// debug_rtx(addr);
-- if (flag_mybaserel == 1)
-- asm_fprintf (file, ".w(a4)");
-- else if (flag_mybaserel == 2)
-- asm_fprintf (file, "(a4)");
-+ if (flag_smallcode)
-+ asm_fprintf(file, ":w(pc)");
- }
-+ else if (flag_mybaserel)
++ else
+ {
-+ /* search the decl. */
-+ tree decl = SYMBOL_REF_DECL (addr);
-+ if (!decl)
++ rtx set = single_set (insn);
++ if (set)
++ ii.fledder (set);
++
++ for (rtx next, note = REG_NOTES(insn); note; note = next)
+ {
-+ rtx x = XEXP(addr, 0);
-+ if (CONSTANT_POOL_ADDRESS_P(x))
-+ decl = SYMBOL_REF_DECL (x);
-+ if (!decl)
++ next = XEXP(note, 1);
++ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND)
+ {
-+ x = XEXP(x, 0);
-+ decl = SYMBOL_REF_DECL (x);
++ jump_table = XEXP(note, 0);
+ }
-+ }
++ }
+
-+ /* Qualifies for a4 if common or bss. Do not ref to .text! */
-+ if (decl && (DECL_COMMON (decl) || bss_initializer_p (decl)))
-+ {
-+ if (flag_mybaserel == 1)
-+ asm_fprintf (file, ":W(a4)");
-+ else if (flag_mybaserel == 2)
-+ asm_fprintf (file, ":L(a4)");
-+ }
-+ }
-+#endif
- }
- }
- else
-
-From c72e9ebfc07a0b31d523b9d7428544427fe551b7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Feb 2017 20:15:17 +0100
-Subject: [PATCH 031/303] @B undo a too optimistic change ;)
-
----
- gcc/regrename.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index 9816d3eaf5d2..df4c320700c5 100644
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -408,7 +408,7 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- don't belong to PREFERRED_CLASS to registers that do, even
- though the latters were used not very long ago.
- Also use a register if no best_new_reg was found till now */
-- if (((pass == 0 || !has_preferred_class)
-+ if (((pass == 0)
- && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
- best_new_reg))
- || tick[best_new_reg] > tick[new_reg])
-
-From 181421087bf57fab0f047c47861b5c2a1e745d96 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Mar 2017 21:38:30 +0100
-Subject: [PATCH 032/303] @R add better -fbaserel(32) support for TARGET_AMIGA
-
----
- gcc/BASE-VER | 2 +-
- gcc/config/m68k/amigaos.c | 51 +++++++++++++----
- gcc/config/m68k/amigaos.h | 21 +++----
- gcc/config/m68k/amigaos.opt | 4 +-
- gcc/config/m68k/m68k.c | 130 ++++++++++++++++++++++++++++--------------
- gcc/config/m68k/m68k.md | 6 +-
- gcc/config/m68k/m68kamigaos.h | 23 ++++++++
- gcc/config/m68k/predicates.md | 4 ++
- 8 files changed, 170 insertions(+), 71 deletions(-)
-
-diff --git a/gcc/BASE-VER b/gcc/BASE-VER
-index b557a4031409..6352d5267189 100644
---- gcc/BASE-VER
-+++ gcc/BASE-VER
-@@ -1 +1 @@
--6.3.1a
-+6.3.1b
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 916140bdc628..81d08245b580 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -548,13 +548,13 @@ _m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
- }
- }
-
--// if (reg == AMIGAOS_MAX_REGPARM && altregbegin != -1)
--// {
--// DPRINTF(("look for alt reg\n"));
--// regbegin = altregbegin;
--// altregbegin = -1;
--// goto look_for_reg;
--// }
-+ if (reg == AMIGAOS_MAX_REGPARM && altregbegin != -1)
-+ {
-+ DPRINTF(("look for alt reg\n"));
-+ regbegin = altregbegin;
-+ altregbegin = -1;
-+ goto look_for_reg;
+ }
- }
-
- if (cum->last_arg_reg != -1)
-@@ -775,9 +775,10 @@ amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
- int *total, bool speed)
- {
- // DPRINTF(("outer: %d, opno: %d", outer_code, opno));
--// debug_rtx(x);
- bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
-- *total *= 4;
-+// *total *= 4;
-+// fprintf(stderr, "costs: %d, mode=%d, outer=%d, opno=%d, speed=%d, ok=%d\n", *total * 4, mode, outer_code, opno, speed, r);
-+// debug_rtx(x);
- return r;
- }
-
-@@ -789,7 +790,37 @@ amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_U
- {
- if (0 == strncmp(".text", name, 5))
- name = ".text";
--// fprintf (asm_out_file, "\t.section\t%s\n", name);
- fprintf (asm_out_file, "\t%s\n", name);
- }
-
-+/* Baserel support. */
++ }
++ else if (NOTE_P(insn))
++ {
++ if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
++ inproepilogue = IN_CODE;
++ else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
++ inproepilogue = IN_EPILOGUE;
++ }
++ }
++ scan_starts.insert (infos.size () - 1);
++ update_insn2index ();
++ update_insn_infos ();
+
-+/**
-+ * Does x reference the pic_reg and is const or plus?
-+ */
-+int amiga_is_const_pic_ref(const_rtx x)
-+{
-+ const_rtx y = x;
-+ if (flag_pic < 3)
-+ return false;
-+ while (GET_CODE(y) == CONST || GET_CODE(y) == PLUS)
-+ y = XEXP(y, 0);
-+ return (x != y && REG_P(y) && REGNO(y) == PIC_REG);
++ return result;
+}
+
-+
-+/* 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)
++/* convert the lowest set bit into a register number. */
++static int
++bit2regno (unsigned bit)
+{
-+ 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;
-+}
-+
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index afc2c6563143..9820f0ed1219 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -221,18 +221,6 @@ while (0)
-
- #if 0
-
--/* 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).
-@@ -492,3 +480,12 @@ while (0)
- bool
- amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-
-+/* SBF: macro to test for const via pic_reg. */
-+#define CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x) \
-+ (GET_CODE(x) == CONST \
-+ && GET_CODE(XEXP(x, 0)) == PLUS \
-+ && REG_P(XEXP(XEXP(x, 0), 0)) \
-+ && REGNO(XEXP(XEXP(x, 0), 0)) == PIC_REG \
-+ && GET_CODE(XEXP(XEXP(x, 0), 1)) == CONST \
-+ && GET_CODE(XEXP(XEXP(XEXP(x, 0), 1), 0)) == UNSPEC \
-+ )
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 1faa3f2eeb26..4d9a42052355 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -12,11 +12,11 @@ Target RejectNegative Var(flag_smallcode,1)
- small code model
-
- fbaserel
--Target Common Report Var(flag_mybaserel,1)
-+Target Report Var(flag_pic,3)
- data is adressed relativ to a4
-
- fbaserel32
--Target Common Report Var(flag_mybaserel,2)
-+Target Report Var(flag_pic,4)
- data is adressed relativ to a4 with 32 bit offsets
-
- resident
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index b6ef99024ea6..64dcbf6969ee 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -591,7 +591,8 @@ m68k_option_override (void)
- if (TARGET_PCREL && flag_pic == 0)
- flag_pic = 1;
-
-- if (!flag_pic)
-+ /* SBF: use normal jumps/calls with baserel(32) modes. */
-+ if (!flag_pic || flag_pic > 2)
- {
- m68k_symbolic_call_var = M68K_SYMBOLIC_CALL_JSR;
-
-@@ -888,8 +889,9 @@ m68k_save_reg (unsigned int regno, bool interrupt_handler)
- {
- if (crtl->saves_all_registers)
- return true;
-+ /* SBF: do not save the PIC_REG with baserel(32) modes. */
- if (crtl->uses_pic_offset_table)
-- return true;
-+ return flag_pic < 3;
- /* Reload may introduce constant pool references into a function
- that thitherto didn't need a PIC register. Note that the test
- above will not catch that case because we will only set
-@@ -1149,8 +1151,9 @@ m68k_expand_prologue (void)
- current_frame.reg_mask, true, true));
- }
-
-+ /* SBF: do not load the PIC_REG with baserel(32) */
- if (!TARGET_SEP_DATA
-- && crtl->uses_pic_offset_table)
-+ && crtl->uses_pic_offset_table && flag_pic < 3)
- emit_insn (gen_load_got (pic_offset_table_rtx));
- }
-
-@@ -2135,6 +2138,12 @@ m68k_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
- {
- struct m68k_address address;
-
-+#ifdef TARGET_AMIGA
-+ /* SBF: the baserel(32) const plus pic_ref, symbol is an address. */
-+ if (amiga_is_const_pic_ref(x))
-+ return true;
-+#endif
-+
- return m68k_decompose_address (mode, x, strict_p, &address);
- }
-
-@@ -2468,9 +2477,33 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
- {
- gcc_assert (reg);
-- pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
-- pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
--// debug_rtx(pic_ref);
-+ if (flag_pic < 3)
-+ {
-+ pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
-+ pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
-+ }
-+ #ifdef TARGET_AMIGA
-+ else
-+ {
-+ tree decl = SYMBOL_REF_DECL (orig);
-+
-+ /* SBF: Does the symbol use common or bss and qualifies for pic_reg?
-+ * Do not ref to .text via pic_reg!
-+ */
-+ if (!SYMBOL_REF_FUNCTION_P(orig) && decl && (DECL_COMMON (decl) || bss_initializer_p (decl)))
-+ {
-+ /* SBF: unfortunately using the wrapped symbol without MEM does not work.
-+ * The pic_ref reference gets decomposed and leads to no working code.
-+ */
-+ pic_ref = m68k_wrap_symbol (pic_ref, RELOC_GOT, m68k_get_gp (), reg);
++ if (!bit)
++ return -1;
+
-+ /* SBF: adding const avoids decomposing. */
-+ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
-+ }
-+ else
-+ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
-+ }
-+#endif
- }
- else if (GET_CODE (orig) == CONST)
- {
-@@ -2489,7 +2522,8 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
- base == reg ? 0 : reg);
-
-- if (GET_CODE (orig) == CONST_INT)
-+ /* SBF: use normal plus and rely on optimizer with baserel(32). */
-+ if (flag_pic < 3 && GET_CODE (orig) == CONST_INT)
- pic_ref = plus_constant (Pmode, base, INTVAL (orig));
- else
- pic_ref = gen_rtx_PLUS (Pmode, base, orig);
-@@ -4453,7 +4487,6 @@ floating_exact_log2 (rtx x)
- void
- print_operand (FILE *file, rtx op, int letter)
- {
--// printf("letter: %c\n", letter);
- if (letter == '.')
- {
- if (MOTOROLA)
-@@ -4486,7 +4519,9 @@ print_operand (FILE *file, rtx op, int letter)
- else if (letter == 'p')
- {
- output_addr_const (file, op);
-- if (!(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
-+ /* SBF: do not add @PLTPC with baserel(32). */
-+ if (flag_pic < 3
-+ && !(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
- fprintf (file, "@PLTPC");
- }
- else if (GET_CODE (op) == REG)
-@@ -4505,10 +4540,12 @@ print_operand (FILE *file, rtx op, int letter)
- && CONSTANT_ADDRESS_P (XEXP (op, 0))
- && !(GET_CODE (XEXP (op, 0)) == CONST_INT
- && INTVAL (XEXP (op, 0)) < 0x8000
-- && INTVAL (XEXP (op, 0)) >= -0x8000))
-+ && INTVAL (XEXP (op, 0)) >= -0x8000)
- #ifdef TARGET_AMIGA
-- if (!flag_mybaserel)
-+/* SBF: Do not append some 'l' with baserel(32). */
-+ && !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(op, 0))
- #endif
-+ )
- fprintf (file, MOTOROLA ? ".l" : ":l");
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
-@@ -4554,9 +4591,18 @@ m68k_get_reloc_decoration (enum m68k_reloc reloc)
- switch (reloc)
- {
- case RELOC_GOT:
--// if (TARGET_AMIGA)
--// return "";
--// else
-+ /* SBF: add the proper extension for baserel relocs with baserel(32). */
-+ if (TARGET_AMIGA)
-+ {
-+ if (flag_pic == 1)
-+ return ".w";
-+ else if (flag_pic == 3)
-+ return ":W";
-+ else if (flag_pic == 4)
-+ return ":L";
-+ else
-+ return "";
-+ }
- if (MOTOROLA)
- {
- if (flag_pic == 1 && TARGET_68020)
-@@ -4707,6 +4753,22 @@ print_operand_address (FILE *file, rtx addr)
- {
- struct m68k_address address;
-
-+#ifdef TARGET_AMIGA
-+ /*
-+ * SBF: remove the const wrapper.
-+ */
-+ if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(addr))
++ unsigned regno = 0;
++ while (!(bit & 1))
+ {
-+ print_operand_address(file, XEXP(addr, 0));
-+ return;
++ ++regno;
++ bit >>= 1;
+ }
-+ if (symbolic_operand(addr, VOIDmode))
++ return regno;
++}
++
++/* check if that register is touched between from and to, excluding from and to .*/
++static bool
++is_reg_touched_between (unsigned regno, int from, int to)
++{
++ for (int index = from + 1; index < to; ++index)
+ {
-+ memset (&address, 0, sizeof (address));
-+ address.offset = addr;
++ insn_info & ii = infos[index];
++ if (ii.is_myuse (regno) || ii.is_def (regno))
++ return true;
+ }
-+ else
-+#endif
- if (!m68k_decompose_address (QImode, addr, true, &address))
- gcc_unreachable ();
-
-@@ -4757,31 +4819,6 @@ print_operand_address (FILE *file, rtx addr)
- if (flag_smallcode)
- asm_fprintf(file, ":w(pc)");
- }
-- else if (flag_mybaserel)
-- {
-- /* search the decl. */
-- tree decl = SYMBOL_REF_DECL (addr);
-- if (!decl)
-- {
-- rtx x = XEXP(addr, 0);
-- if (CONSTANT_POOL_ADDRESS_P(x))
-- decl = SYMBOL_REF_DECL (x);
-- if (!decl)
-- {
-- x = XEXP(x, 0);
-- decl = SYMBOL_REF_DECL (x);
-- }
-- }
--
-- /* Qualifies for a4 if common or bss. Do not ref to .text! */
-- if (decl && (DECL_COMMON (decl) || bss_initializer_p (decl)))
-- {
-- if (flag_mybaserel == 1)
-- asm_fprintf (file, ":W(a4)");
-- else if (flag_mybaserel == 2)
-- asm_fprintf (file, ":L(a4)");
-- }
-- }
- #endif
- }
- }
-@@ -5224,7 +5261,9 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
-
- /* Value is true if hard register REGNO can hold a value of machine-mode
- MODE. On the 68000, we let the cpu registers can hold any mode, but
-- restrict the 68881 registers to floating-point modes. */
-+ restrict the 68881 registers to floating-point modes.
-+ SBF: Disallow the frame pointer register, if the frame pointer is used.
-+ */
-
- bool
- m68k_regno_mode_ok (int regno, machine_mode mode)
-@@ -5233,12 +5272,12 @@ m68k_regno_mode_ok (int regno, machine_mode mode)
- {
- /* Data Registers, can hold aggregate if fits in. */
- if (regno + GET_MODE_SIZE (mode) / 4 <= 8)
-- return true;
-+ return !flag_omit_frame_pointer || regno != FRAME_POINTER_REGNUM;
- }
- else if (ADDRESS_REGNO_P (regno))
- {
- if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
-- return true;
-+ return !flag_omit_frame_pointer || regno != FRAME_POINTER_REGNUM;
- }
- else if (FP_REGNO_P (regno))
- {
-@@ -5259,6 +5298,13 @@ m68k_secondary_reload_class (enum reg_class rclass,
- machine_mode mode, rtx x)
- {
- int regno;
-+#ifdef TARGET_AMIGA
-+ /* SBF: check for baserel's const pic_ref
-+ * and return ADDR_REGS or NO_REGS
-+ */
-+ if (!MEM_P(x) && amiga_is_const_pic_ref(x))
-+ return rclass == ADDR_REGS ? NO_REGS : ADDR_REGS;
-+#endif
-
- regno = true_regnum (x);
-
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index f5b63f43c372..24332476b91b 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -128,13 +128,11 @@
- (UNSPECV_TAS_2 4)
- ])
-
--;; Registers by name.
-+;; Registers by name. SBF: Do not define PIC_REG / A6_REG here!
- (define_constants
- [(D0_REG 0)
- (A0_REG 8)
- (A1_REG 9)
-- (PIC_REG 13)
-- (A6_REG 14)
- (SP_REG 15)
- (FP0_REG 16)
- ])
-@@ -502,7 +500,7 @@
- [(set (cc0)
- (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mr,ma,>")
- (match_operand:SI 1 "general_operand" "mr,ma,KTr,Ksr,>")))]
-- "!TARGET_COLDFIRE"
-+ "!TARGET_COLDFIRE && (flag_pic < 3 || GET_CODE(operands[1]) != CONST || GET_CODE(XEXP(operands[1], 0)) != PLUS || !REG_P(XEXP(XEXP(operands[1], 0), 0)) || REGNO(XEXP(XEXP(operands[1], 0), 0)) != PIC_REG)"
- {
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- return "cmpm%.l %1,%0";
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 539d5f0bf934..74403a50bb67 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -578,3 +578,26 @@ amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
-
- // this disables tree_loop_distribute_patterns
- #define C_COMMON_OVERRIDE_OPTIONS flag_no_builtin = 1
-+/* Baserel support. */
-+
-+extern int amiga_is_const_pic_ref(const_rtx x);
++ return false;
++}
+
-+#undef CONSTANT_ADDRESS_P
-+#define CONSTANT_ADDRESS_P(X) \
-+((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
-+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
-+ || GET_CODE (X) == HIGH \
-+ ) && !amiga_is_const_pic_ref(X))
++/*
++ * search backward and find the initial assignment for that regno.
++ */
++static unsigned
++find_start (unsigned start, unsigned rename_regno)
++{
++ /* search the start. */
++ while (start > 0)
++ {
++ unsigned startm1 = start - 1;
+
++ /* do not run over RETURNS */
++ insn_info & jj = infos[start];
+
-+/* Given that symbolic_operand(X), return TRUE if no special
-+ base relative relocation is necessary */
++ /* stop at labels. If a label is a start pos, a search is maybe started again. */
++ if (jj.is_label ())
++ break;
+
-+#define LEGITIMATE_BASEREL_OPERAND_P(X) \
-+ (flag_pic >= 3 && read_only_operand (X))
++ insn_info & bb = infos[startm1];
++ if (jj.in_proepi () == IN_CODE && bb.in_proepi () >= IN_EPILOGUE)
++ break;
+
-+#undef LEGITIMATE_PIC_OPERAND_P
-+#define LEGITIMATE_PIC_OPERAND_P(X) ( \
-+ ! symbolic_operand (X, VOIDmode) || LEGITIMATE_BASEREL_OPERAND_P (X))
++ /* found the definition without use. */
++ if (jj.is_def (rename_regno) && !jj.is_use (rename_regno))
++ break;
+
-+// (GET_CODE(X) == CONST && (GET_CODE(XEXP(X, 0)) == SYMBOL_REF || GET_CODE(XEXP(X, 0)) == LABEL_REF) && !CONSTANT_POOL_ADDRESS_P (XEXP(X, 0))) ||
-diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
-index 186436c42b77..9533e65ceaab 100644
---- gcc/config/m68k/predicates.md
-+++ gcc/config/m68k/predicates.md
-@@ -30,6 +30,10 @@
- || GET_CODE (XEXP (op, 0)) == LABEL_REF
- || GET_CODE (XEXP (op, 0)) == CONST))
- return 1;
-+#ifdef TARGET_AMIGA
-+ if (flag_pic >= 3 && amiga_is_const_pic_ref(op))
-+ return 0;
-+#endif
- return general_operand (op, mode);
- })
-
-
-From e74ef22307cef4b728ea06a9bb78f24d3c7879d6 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 20 Mar 2017 22:47:47 +0100
-Subject: [PATCH 033/303] @R improved register renamingRegister renaming now
- updates the register ref count. Also the stack variable creation is scheduled
- later, to omitt push/pop of unused variables.The regs d0/a0 are preferred and
- rarely renamed.
-
----
- gcc/calls.c | 2 +-
- gcc/config/m68k/amigaos.c | 9 +++++
- gcc/config/m68k/amigaos.h | 5 +++
- gcc/config/m68k/m68k.c | 12 ++++---
- gcc/config/m68k/m68k.h | 10 +++---
- gcc/df-scan.c | 7 ++++
- gcc/doc/tm.texi | 4 +++
- gcc/doc/tm.texi.in | 2 ++
- gcc/expr.c | 2 +-
- gcc/passes.def | 6 ++--
- gcc/regrename.c | 84 +++++++++++++++++++++++++++--------------------
- gcc/target.def | 19 +++++++++++
- gcc/targhooks.c | 7 ++++
- gcc/targhooks.h | 1 +
- 14 files changed, 120 insertions(+), 50 deletions(-)
-
-diff --git a/gcc/calls.c b/gcc/calls.c
-index 730d82e65cf3..c78059fb5199 100644
---- gcc/calls.c
-+++ gcc/calls.c
-@@ -21,12 +21,12 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
--#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
- #include "gimple.h"
- #include "predict.h"
-+#include "tm_p.h"
- #include "stringpool.h"
- #include "expmed.h"
- #include "optabs.h"
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 81d08245b580..88205e25476e 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -824,3 +824,12 @@ read_only_operand (rtx operand)
- return 1;
- }
-
-+reg_class_t
-+amiga_preferred_rename_class2(reg_class_t rclass ATTRIBUTE_UNUSED, int regno )
-+{
-+ if (regno == 0)
-+ return D0_REGS;
-+ if (regno == 8)
-+ return A0_REGS;
-+ return regno_reg_class[regno];
++ start = startm1;
++ }
++ return start;
+}
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 9820f0ed1219..7259611edc9e 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -489,3 +489,8 @@ amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
- && GET_CODE(XEXP(XEXP(x, 0), 1)) == CONST \
- && GET_CODE(XEXP(XEXP(XEXP(x, 0), 1), 0)) == UNSPEC \
- )
-+
-+#undef TARGET_PREFERRED_RENAME_CLASS2
-+#define TARGET_PREFERRED_RENAME_CLASS2 amiga_preferred_rename_class2
-+reg_class_t
-+amiga_preferred_rename_class2(reg_class_t, int);
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 64dcbf6969ee..d60371a92bc6 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -801,9 +801,11 @@ m68k_compute_frame_layout (void)
-
- /* Only compute the frame once per function.
- Don't cache information until reload has been completed. */
-- if (current_frame.funcdef_no == current_function_funcdef_no
-- && reload_completed)
-- return;
-+ /* SBF: No. Register renaming may free some variables,
-+ * => compute it again and again... */
-+// if (current_frame.funcdef_no == current_function_funcdef_no
-+// && reload_completed)
-+// return;
-
- current_frame.size = (get_frame_size () + 3) & -4;
-
-@@ -5272,12 +5274,12 @@ m68k_regno_mode_ok (int regno, machine_mode mode)
- {
- /* Data Registers, can hold aggregate if fits in. */
- if (regno + GET_MODE_SIZE (mode) / 4 <= 8)
-- return !flag_omit_frame_pointer || regno != FRAME_POINTER_REGNUM;
-+ return true;
- }
- else if (ADDRESS_REGNO_P (regno))
- {
- if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
-- return !flag_omit_frame_pointer || regno != FRAME_POINTER_REGNUM;
-+ return !frame_pointer_needed || regno != FRAME_POINTER_REGNUM;
- }
- else if (FP_REGNO_P (regno))
- {
-diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
-index 74d5aa042059..5142adf24e4d 100644
---- gcc/config/m68k/m68k.h
-+++ gcc/config/m68k/m68k.h
-@@ -440,8 +440,8 @@ along with GCC; see the file COPYING3. If not see
- /* The m68k has three kinds of registers, so eight classes would be
- a complete set. One of them is not needed. */
- enum reg_class {
-- NO_REGS, DATA_REGS,
-- ADDR_REGS, FP_REGS,
-+ NO_REGS, DATA_REGS, D0_REGS,
-+ ADDR_REGS, A0_REGS, FP_REGS,
- GENERAL_REGS, DATA_OR_FP_REGS,
- ADDR_OR_FP_REGS, ALL_REGS,
- LIM_REG_CLASSES };
-@@ -449,8 +449,8 @@ enum reg_class {
- #define N_REG_CLASSES (int) LIM_REG_CLASSES
-
- #define REG_CLASS_NAMES \
-- { "NO_REGS", "DATA_REGS", \
-- "ADDR_REGS", "FP_REGS", \
-+ { "NO_REGS", "DATA_REGS", "D0_REGS" \
-+ "ADDR_REGS", "A0_REGS", "FP_REGS", \
- "GENERAL_REGS", "DATA_OR_FP_REGS", \
- "ADDR_OR_FP_REGS", "ALL_REGS" }
-
-@@ -458,7 +458,9 @@ enum reg_class {
- { \
- {0x00000000}, /* NO_REGS */ \
- {0x000000ff}, /* DATA_REGS */ \
-+ {0x00000001}, /* D0_REGS */ \
- {0x0100ff00}, /* ADDR_REGS */ \
-+ {0x00000100}, /* A0_REGS */ \
- {0x00ff0000}, /* FP_REGS */ \
- {0x0100ffff}, /* GENERAL_REGS */ \
- {0x00ff00ff}, /* DATA_OR_FP_REGS */ \
-diff --git a/gcc/df-scan.c b/gcc/df-scan.c
-index 98de84405428..b0ef0813d07d 100644
---- gcc/df-scan.c
-+++ gcc/df-scan.c
-@@ -1807,6 +1807,13 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
- df_ref *ref_ptr;
- struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref);
-
-+ if (DF_REF_FLAGS_IS_SET(the_ref, DF_HARD_REG_LIVE))
-+ {
-+ if (DF_REF_REGNO(the_ref) < FIRST_PSEUDO_REGISTER)
-+ --df->hard_regs_live_count[DF_REF_REGNO(the_ref)];
-+ ++df->hard_regs_live_count[new_regno];
-+ }
+
- DF_REF_REGNO (the_ref) = new_regno;
- DF_REF_REG (the_ref) = regno_reg_rtx[new_regno];
-
-diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
-index 745910f9a331..6604514427fa 100644
---- gcc/doc/tm.texi
-+++ gcc/doc/tm.texi
-@@ -2489,6 +2489,10 @@ only if neither labeling works.
- A target hook that places additional preference on the register class to use when it is necessary to rename a register in class @var{rclass} to another class, or perhaps @var{NO_REGS}, if no preferred register class is found or hook @code{preferred_rename_class} is not implemented. Sometimes returning a more restrictive class makes better code. For example, on ARM, thumb-2 instructions using @code{LO_REGS} may be smaller than instructions using @code{GENERIC_REGS}. By returning @code{LO_REGS} from @code{preferred_rename_class}, code size can be reduced.
- @end deftypefn
-
-+@deftypefn {Target Hook} reg_class_t TARGET_PREFERRED_RENAME_CLASS2 (reg_class_t @var{rclass}, int @var{regno})
-+A target hook that places additional preference on the register class to use when it is necessary to rename a register in class @var{rclass} to another class, or perhaps @var{NO_REGS}, if no preferred register class is found or hook @code{preferred_rename_class2} is not implemented. Sometimes returning a more restrictive class makes better code. For example, on ARM, thumb-2 instructions using @code{LO_REGS} may be smaller than instructions using @code{GENERIC_REGS}. By returning @code{LO_REGS} from @code{preferred_rename_class2}, code size can be reduced.
-+@end deftypefn
-+
- @deftypefn {Target Hook} reg_class_t TARGET_PREFERRED_RELOAD_CLASS (rtx @var{x}, reg_class_t @var{rclass})
- A target hook that places additional restrictions on the register class
- to use when it is necessary to copy value @var{x} into a register in class
-diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
-index f31c763991c5..e4da2a94249b 100644
---- gcc/doc/tm.texi.in
-+++ gcc/doc/tm.texi.in
-@@ -2281,6 +2281,8 @@ only if neither labeling works.
-
- @hook TARGET_PREFERRED_RENAME_CLASS
-
-+@hook TARGET_PREFERRED_RENAME_CLASS2
++/*
++ * Always prefer lower register numbers within the class.
++ */
++static unsigned
++opt_reg_rename (void)
++{
++ update_label2jump ();
++// dump_insns ("rename", 1);
++ for (unsigned index = 0; index < infos.size (); ++index)
++ {
++ insn_info & ii = infos[index];
+
- @hook TARGET_PREFERRED_RELOAD_CLASS
-
- @defmac PREFERRED_RELOAD_CLASS (@var{x}, @var{class})
-diff --git a/gcc/expr.c b/gcc/expr.c
-index 01fe6437da12..6260f5ed7ed2 100644
---- gcc/expr.c
-+++ gcc/expr.c
-@@ -21,12 +21,12 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
--#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
- #include "gimple.h"
- #include "predict.h"
-+#include "tm_p.h"
- #include "ssa.h"
- #include "expmed.h"
- #include "optabs.h"
-diff --git a/gcc/passes.def b/gcc/passes.def
-index 7aed14445429..ec796082ae7f 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -447,9 +447,6 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_ree);
- NEXT_PASS (pass_compare_elim_after_reload);
- NEXT_PASS (pass_branch_target_load_optimize1);
-- NEXT_PASS (pass_thread_prologue_and_epilogue);
-- NEXT_PASS (pass_rtl_dse2);
-- NEXT_PASS (pass_stack_adjustments);
- NEXT_PASS (pass_jump2);
- NEXT_PASS (pass_duplicate_computed_gotos);
- NEXT_PASS (pass_sched_fusion);
-@@ -457,6 +454,9 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_if_after_reload);
- NEXT_PASS (pass_regrename);
- NEXT_PASS (pass_cprop_hardreg);
-+ NEXT_PASS (pass_thread_prologue_and_epilogue);
-+ NEXT_PASS (pass_rtl_dse2);
-+ NEXT_PASS (pass_stack_adjustments);
- NEXT_PASS (pass_fast_rtl_dce);
- NEXT_PASS (pass_reorder_blocks);
- NEXT_PASS (pass_branch_target_load_optimize2);
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index df4c320700c5..ca7e24774afd 100644
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -370,32 +370,31 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
-
- /* Compute preferred rename class of super union of all the classes
- in the chain. */
-- preferred_class
-- = (enum reg_class) targetm.preferred_rename_class (super_class);
-+ preferred_class = (enum reg_class) targetm.preferred_rename_class2 (
-+ super_class, old_reg);
-
- /* Pick and check the register from the tied chain iff the tied chain
-- is not renamed. */
-+ is not renamed. */
- if (this_head->tied_chain && !this_head->tied_chain->renamed
-- && check_new_reg_p (old_reg, this_head->tied_chain->regno,
-- this_head, *unavailable))
-+ && check_new_reg_p (old_reg, this_head->tied_chain->regno, this_head,
-+ *unavailable))
- return this_head->tied_chain->regno;
-
- /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
-- over registers that belong to PREFERRED_CLASS and try to find the
-- best register within the class. If that failed, we iterate in
-- the second pass over registers that don't belong to the class.
-- If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
-- ascending order without any preference. */
-+ over registers that belong to PREFERRED_CLASS and try to find the
-+ best register within the class. If that failed, we iterate in
-+ the second pass over registers that don't belong to the class.
-+ If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
-+ ascending order without any preference. */
- has_preferred_class = (preferred_class != NO_REGS);
-- for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
- {
- int new_reg;
- for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
- {
- if (has_preferred_class
-- && (pass == 0)
-- != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
-- new_reg))
-+ && 0
-+ == TEST_HARD_REG_BIT(reg_class_contents[preferred_class],
-+ new_reg))
- continue;
-
- if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
-@@ -405,17 +404,13 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- return new_reg;
-
- /* In the first pass, we force the renaming of registers that
-- don't belong to PREFERRED_CLASS to registers that do, even
-- though the latters were used not very long ago.
-- Also use a register if no best_new_reg was found till now */
-- if (((pass == 0)
-- && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
-- best_new_reg))
-- || tick[best_new_reg] > tick[new_reg])
-+ don't belong to PREFERRED_CLASS to registers that do, even
-+ though the latters were used not very long ago.
-+ Also use a register if no best_new_reg was found till now */
-+ if ((tick[best_new_reg] > tick[new_reg]
-+ || (old_reg == best_new_reg && new_reg < old_reg)))
- best_new_reg = new_reg;
- }
-- if (pass == 0 && best_new_reg != old_reg)
-- break;
- }
- return best_new_reg;
- }
-@@ -955,7 +950,7 @@ regrename_analyze (bitmap bb_mask)
- numbering in its subpatterns. */
-
- bool
--regrename_do_replace (struct du_head *head, int reg)
-+regrename_do_replace (struct du_head *head, int regno)
- {
- struct du_chain *chain;
- unsigned int base_regno = head->regno;
-@@ -963,19 +958,20 @@ regrename_do_replace (struct du_head *head, int reg)
-
- for (chain = head->first; chain; chain = chain->next_use)
- {
-- unsigned int regno = ORIGINAL_REGNO (*chain->loc);
-- struct reg_attrs *attr = REG_ATTRS (*chain->loc);
-- int reg_ptr = REG_POINTER (*chain->loc);
-+ unsigned int orig_regno = ORIGINAL_REGNO(*chain->loc);
-+ struct reg_attrs *attr = REG_ATTRS(*chain->loc);
-+ int reg_ptr = REG_POINTER(*chain->loc);
-
- if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
-- validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
-- gen_rtx_UNKNOWN_VAR_LOC (), true);
-+ validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC(chain->insn)),
-+ gen_rtx_UNKNOWN_VAR_LOC (),
-+ true);
- else
- {
-- validate_change (chain->insn, chain->loc,
-- gen_raw_REG (GET_MODE (*chain->loc), reg), true);
-- if (regno >= FIRST_PSEUDO_REGISTER)
-- ORIGINAL_REGNO (*chain->loc) = regno;
-+ validate_change (chain->insn, chain->loc,
-+ gen_raw_REG (GET_MODE(*chain->loc), regno), true);
-+ if (orig_regno >= FIRST_PSEUDO_REGISTER)
-+ ORIGINAL_REGNO (*chain->loc) = orig_regno;
- REG_ATTRS (*chain->loc) = attr;
- REG_POINTER (*chain->loc) = reg_ptr;
- }
-@@ -984,10 +980,26 @@ regrename_do_replace (struct du_head *head, int reg)
- if (!apply_change_group ())
- return false;
-
-- mode = GET_MODE (*head->first->loc);
-+ mode = GET_MODE(*head->first->loc);
- head->renamed = 1;
-- head->regno = reg;
-- head->nregs = hard_regno_nregs[reg][mode];
-+ head->regno = regno;
-+ head->nregs = hard_regno_nregs[regno][mode];
++ /* do not rename if register is hard or used in same statement. */
++ const unsigned rename_regbit = ii.get_regbit ();
++ if (!rename_regbit)
++ continue;
+
-+ /* SBF: also update the current df info, move from base_regno -> regno. */
-+ for (chain = head->first; chain; chain = chain->next_use)
-+ {
-+ /* undo regno patch - will be patched again */
-+ if (REGNO (*chain->loc) == regno)
-+ SET_REGNO(*chain->loc, base_regno);
-+ df_ref_change_reg_with_loc (*chain->loc, regno);
++ const unsigned rename_regno = bit2regno (rename_regbit);
+
-+ SET_REGNO(*chain->loc, regno);
-+ }
++ /* get the mask for free registers. */
++ unsigned mask = ii.get_free_mask ();
+
-+ /* Mark the old regno as no longer used. */
-+ if (!df->hard_regs_live_count[base_regno])
-+ df_set_regs_ever_live (base_regno, false);
++ /* the mask contains the current src register. Add this register to the mask if it's dead here. */
++ if (ii.get_src_reg () && is_reg_dead (ii.get_src_regno (), index))
++ mask |= ii.get_use ();
+
- return true;
- }
-
-diff --git a/gcc/target.def b/gcc/target.def
-index 20f2b32da1e9..d0208812d83b 100644
---- gcc/target.def
-+++ gcc/target.def
-@@ -5170,6 +5170,25 @@ DEFHOOK
- reg_class_t, (reg_class_t rclass),
- default_preferred_rename_class)
-
-+/*A target hook that places additional preference on the register
-+ class
-+ */
-+DEFHOOK
-+(preferred_rename_class2,
-+ "A target hook that places additional preference on the register\
-+ class to use when it is necessary to rename a register in class\
-+ @var{rclass} to another class, or perhaps @var{NO_REGS}, if no\
-+ preferred register class is found or hook @code{preferred_rename_class2}\
-+ is not implemented.\
-+ Sometimes returning a more restrictive class makes better code. For\
-+ example, on ARM, thumb-2 instructions using @code{LO_REGS} may be\
-+ smaller than instructions using @code{GENERIC_REGS}. By returning\
-+ @code{LO_REGS} from @code{preferred_rename_class2}, code size can\
-+ be reduced.",
-+ reg_class_t, (reg_class_t rclass, int regno),
-+ default_preferred_rename_class2)
-+
-+
- /* This target hook allows the backend to avoid unsafe substitution
- during register allocation. */
- DEFHOOK
-diff --git a/gcc/targhooks.c b/gcc/targhooks.c
-index a34227705d2b..e106af7b261d 100644
---- gcc/targhooks.c
-+++ gcc/targhooks.c
-@@ -1542,6 +1542,13 @@ default_preferred_rename_class (reg_class_t rclass ATTRIBUTE_UNUSED)
- return NO_REGS;
- }
-
-+/* The default implementation of TARGET_PREFERRED_RENAME_CLASS2. */
-+reg_class_t
-+default_preferred_rename_class2 (reg_class_t rclass, int regno ATTRIBUTE_UNUSED)
-+{
-+ return targetm.preferred_rename_class(rclass);
-+}
++ /* do not use a4 if compiling baserel */
++ if (flag_pic >= 3)
++ mask &= ~(1 << PIC_REG);
+
- /* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P. */
-
- bool
-diff --git a/gcc/targhooks.h b/gcc/targhooks.h
-index 7687c39b53b5..0a21ef982a65 100644
---- gcc/targhooks.h
-+++ gcc/targhooks.h
-@@ -204,6 +204,7 @@ extern bool default_profile_before_prologue (void);
- extern reg_class_t default_preferred_reload_class (rtx, reg_class_t);
- extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t);
- extern reg_class_t default_preferred_rename_class (reg_class_t rclass);
-+extern reg_class_t default_preferred_rename_class2 (reg_class_t rclass, int regno);
- extern bool default_class_likely_spilled_p (reg_class_t);
- extern unsigned char default_class_max_nregs (reg_class_t, machine_mode);
-
-
-From 6b9057baef40c5661b35c995f764401a82fcf9b7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 20 Mar 2017 23:11:56 +0100
-Subject: [PATCH 034/303] @B fix include order
-
----
- gcc/function.c | 2 +-
- gcc/var-tracking.c | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/function.c b/gcc/function.c
-index e903b1bcdf65..c614f9b9c000 100644
---- gcc/function.c
-+++ gcc/function.c
-@@ -35,11 +35,11 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
--#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
- #include "gimple-expr.h"
-+#include "tm_p.h"
- #include "cfghooks.h"
- #include "df.h"
- #include "stringpool.h"
-diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
-index 149c0c123804..ab9c0117b078 100644
---- gcc/var-tracking.c
-+++ gcc/var-tracking.c
-@@ -89,10 +89,10 @@
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
--#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
-+#include "tm_p.h"
- #include "cfghooks.h"
- #include "alloc-pool.h"
- #include "tree-pass.h"
-
-From 1176f20fb5eb00f735a1c1ad2bb9d005fdac44aa Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 21 Mar 2017 00:15:07 +0100
-Subject: [PATCH 035/303] @B fix pssible NPE
-
----
- gcc/regrename.c | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index ca7e24774afd..4a9b4c2735a1 100644
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -986,15 +986,18 @@ regrename_do_replace (struct du_head *head, int regno)
- head->nregs = hard_regno_nregs[regno][mode];
-
- /* SBF: also update the current df info, move from base_regno -> regno. */
-- for (chain = head->first; chain; chain = chain->next_use)
-- {
-- /* undo regno patch - will be patched again */
-- if (REGNO (*chain->loc) == regno)
-- SET_REGNO(*chain->loc, base_regno);
-- df_ref_change_reg_with_loc (*chain->loc, regno);
-+ if (base_regno < FIRST_PSEUDO_REGISTER && regno < FIRST_PSEUDO_REGISTER)
-+ for (chain = head->first; chain; chain = chain->next_use)
-+ {
-+ if (DEBUG_INSN_P (chain->insn))
-+ continue;
-+ /* undo regno patch - will be patched again */
-+ if (REGNO (*chain->loc) == regno)
-+ SET_REGNO(*chain->loc, base_regno);
-+ df_ref_change_reg_with_loc (*chain->loc, regno);
-
-- SET_REGNO(*chain->loc, regno);
-- }
-+ SET_REGNO(*chain->loc, regno);
-+ }
-
- /* Mark the old regno as no longer used. */
- if (!df->hard_regs_live_count[base_regno])
-
-From 5844c3b50f6c2e52c83592a41e570603450d47b4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 22 Mar 2017 15:48:28 +0100
-Subject: [PATCH 036/303] @B decrement ref count correctly
-
----
- gcc/df-scan.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/gcc/df-scan.c b/gcc/df-scan.c
-index b0ef0813d07d..1f23452afe19 100644
---- gcc/df-scan.c
-+++ gcc/df-scan.c
-@@ -1809,8 +1809,7 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
-
- if (DF_REF_FLAGS_IS_SET(the_ref, DF_HARD_REG_LIVE))
- {
-- if (DF_REF_REGNO(the_ref) < FIRST_PSEUDO_REGISTER)
-- --df->hard_regs_live_count[DF_REF_REGNO(the_ref)];
-+ --df->hard_regs_live_count[DF_REF_REGNO(the_ref)];
- ++df->hard_regs_live_count[new_regno];
- }
-
-
-From e9a9e3005a6160dc5e9a4338c5516f3787e657da Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 22 Mar 2017 15:49:15 +0100
-Subject: [PATCH 037/303] @I cleanup
-
----
- gcc/regrename.c | 40 ++++++++++++++++++----------------------
- 1 file changed, 18 insertions(+), 22 deletions(-)
-
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index 4a9b4c2735a1..2dd96db5b87f 100644
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -356,8 +356,8 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- {
- bool has_preferred_class;
- enum reg_class preferred_class;
-- int pass;
- int best_new_reg = old_reg;
-+ int new_reg;
-
- /* Further narrow the set of registers we can use for renaming.
- If the chain needs a call-saved register, mark the call-used
-@@ -387,30 +387,26 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
- ascending order without any preference. */
- has_preferred_class = (preferred_class != NO_REGS);
-+ for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
- {
-- int new_reg;
-- for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
-- {
-- if (has_preferred_class
-- && 0
-- == TEST_HARD_REG_BIT(reg_class_contents[preferred_class],
-- new_reg))
-- continue;
-+ if (has_preferred_class
-+ && !TEST_HARD_REG_BIT(reg_class_contents[preferred_class],
-+ new_reg))
-+ continue;
-
-- if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
-- continue;
-+ if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
++ if (!mask)
+ continue;
-
-- if (!best_rename)
-- return new_reg;
-+ if (!best_rename)
-+ return new_reg;
-
-- /* In the first pass, we force the renaming of registers that
-- don't belong to PREFERRED_CLASS to registers that do, even
-- though the latters were used not very long ago.
-- Also use a register if no best_new_reg was found till now */
-- if ((tick[best_new_reg] > tick[new_reg]
-- || (old_reg == best_new_reg && new_reg < old_reg)))
-- best_new_reg = new_reg;
-- }
-+ /* In the first pass, we force the renaming of registers that
-+ don't belong to PREFERRED_CLASS to registers that do, even
-+ though the latters were used not very long ago.
-+ Also use a register if no best_new_reg was found till now */
-+ if ((tick[best_new_reg] > tick[new_reg]
-+ || (old_reg == best_new_reg && new_reg < old_reg)))
-+ best_new_reg = new_reg;
- }
- return best_new_reg;
- }
-@@ -989,7 +985,7 @@ regrename_do_replace (struct du_head *head, int regno)
- if (base_regno < FIRST_PSEUDO_REGISTER && regno < FIRST_PSEUDO_REGISTER)
- for (chain = head->first; chain; chain = chain->next_use)
- {
-- if (DEBUG_INSN_P (chain->insn))
-+ if (DEBUG_INSN_P (chain->insn) && VAR_LOC_UNKNOWN_P(INSN_VAR_LOCATION_LOC(chain->insn)))
- continue;
- /* undo regno patch - will be patched again */
- if (REGNO (*chain->loc) == regno)
-
-From ed41bbc9c042c73e2c423a93d98b6c83988fc8e3 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 22 Mar 2017 16:02:57 +0100
-Subject: [PATCH 038/303] @R -ftree-loop-vectorize and -ftree-slp-vectorize are
- no longer enabled with -O3
-
----
- gcc/opts.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/gcc/opts.c b/gcc/opts.c
-index 0f9431a0b323..28a617c0f14f 100644
---- gcc/opts.c
-+++ gcc/opts.c
-@@ -530,8 +530,10 @@ static const struct default_options default_options_table[] =
- { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
-+#ifndef TARGET_AMIGA
- { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
-+#endif
- { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
- { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
-
-From 25f75fe3179ceb6da6f50b1c30d8fe810c1ccccd Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 22 Mar 2017 16:05:51 +0100
-Subject: [PATCH 039/303] @N added a new combine optimization.i2 something ->
- regi3 reg -> somewherewithi4 compare reg, const_0is replaced with: something
- -> somewhere, if the reg is dead at the comparison
-
----
- gcc/combine.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 60 insertions(+)
-
-diff --git a/gcc/combine.c b/gcc/combine.c
-index 75c6229766c0..333f8fef9655 100644
---- gcc/combine.c
-+++ gcc/combine.c
-@@ -102,6 +102,7 @@ along with GCC; see the file COPYING3. If not see
- #include "valtrack.h"
- #include "rtl-iter.h"
- #include "print-rtl.h"
-+#include "conditions.h"
-
- #ifndef LOAD_EXTEND_OP
- #define LOAD_EXTEND_OP(M) UNKNOWN
-@@ -2578,6 +2579,7 @@ static rtx_insn *
- try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- int *new_direct_jump_p, rtx_insn *last_combined_insn)
- {
-+ rtx_insn * del4 = 0;
- /* New patterns for I3 and I2, respectively. */
- rtx newpat, newi2pat = 0;
- rtvec newpat_vec_with_clobbers = 0;
-@@ -3350,6 +3352,52 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- substed_i0 = 1;
- }
-
-+#if HAVE_cc0
-+ /* SBF: This is an attempt to combine
-+ * i2 something -> reg
-+ * i3 reg -> somewhere
-+ * with the next insn i4
-+ * i4 compare reg, 0
-+ *
-+ * then
-+ * newpat = something -> somewhere
-+ *
-+ * If the comparison with 0 is already done in the insn newpat
-+ * and the reg is dead at the compare insn
-+ * then perform the combine and mark the compare as deleted.
-+ */
-+ if (i2dest_killed && !i0 && !i1 && i2pat && i2_is_used + added_sets_2 > 1
-+ && NEXT_INSN(i3))
-+ {
-+ rtx_insn *next = NEXT_INSN(i3);
-+ rtx setn = single_set(next);
-+ if (setn)
++
++ /* first = pos to start, second indicates to treat def as use. */
++ std::set<unsigned> todo;
++ std::set<unsigned> found;
++ if (index + 1 < infos.size ())
++ todo.insert (index + 1);
++
++ found.insert (index);
++ /* a register was defined, follow all branches. */
++ while (mask && todo.begin () != todo.end ())
+ {
-+ rtx srcn = SET_SRC(setn);
-+ if (GET_CODE(srcn) == COMPARE)
++ unsigned runpos = *todo.begin ();
++ todo.erase (todo.begin ());
++
++// printf ("runpos %d \n", runpos); fflush (stdout);
++ for (unsigned pos = runpos; mask && pos < infos.size (); ++pos)
+ {
-+ rtx dstn = XEXP(srcn, 0);
-+ srcn = XEXP(srcn, 1);
++ /* already searched. */
++ if (found.find (pos) != found.end ())
++ break;
+
-+ if (CONST_INT_P(srcn) && INTVAL(srcn) == 0
-+ && find_reg_note(next, REG_DEAD, dstn))
++ rtx_insn * insn = infos[pos].get_insn ();
++ if (LABEL_P(insn))
+ {
-+ /* now check via NOTICE_UPDATE_CC*/
-+ NOTICE_UPDATE_CC(PATTERN(i2), i2);
-+ if (cc_status.flags == 0 && rtx_equal_p(dstn, cc_status.value1))
++ found.insert (pos);
++
++ /* for each jump to this label:
++ * check if the reg was used at that jump.
++ * if used, find def
++ */
++ for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
++ i != label2jump.end () && i->first == k->first; ++i)
+ {
-+ added_sets_2 = 0;
-+ i2_is_used = 0;
++ i2i_iterator j = insn2info.find (i->second);
++ if (j == insn2info.end ())
++ {
++ mask = 0;
++ break;
++ }
++
++ unsigned startat = j->second->get_index ();
++ if (found.find (startat) != found.end () || !infos[startat].is_use (rename_regno))
++ continue;
+
-+ /* perform deletion later, if all other checks are ok. */
-+ del4 = next;
++ unsigned start = find_start (startat, rename_regno);
++// printf ("label %d <- jump %d : start %d\n", pos, startat, start); fflush (stdout);
++ todo.insert (start);
+ }
-+ }
-+ }
-+ }
-+ }
-+#endif
+
- /* Fail if an autoincrement side-effect has been duplicated. Be careful
- to count all the ways that I2SRC and I1SRC can be used. */
- if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0
-@@ -4387,6 +4435,18 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- move_deaths (newi2pat, NULL_RTX, from_luid, i2, &midnotes);
- move_deaths (newpat, newi2pat, from_luid, i3, &midnotes);
-
-+ /* SBF: perform the deletion of the next insn, if marked. */
-+ if (del4)
-+ {
-+ int del_from_luid = DF_INSN_LUID(del4);
-+ LOG_LINKS(del4) = NULL;
-+ REG_NOTES(del4) = 0;
-+ SET_INSN_DELETED(del4);
-+ if (newi2pat)
-+ move_deaths(newi2pat, NULL_RTX, del_from_luid, del4, &midnotes);
-+ move_deaths(newpat, NULL_RTX, del_from_luid, del4, &midnotes);
-+ }
++ /* if this label is at a start, check if it is reachable from the previous insn,
++ * and if, check for use then search start. */
++ if (pos > 0)
++ {
++ insn_info & bb = infos[pos - 1];
++ rtx set = single_set (bb.get_insn ());
++ if (ANY_RETURN_P(bb.get_insn ())
++ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) != IF_THEN_ELSE))
++ continue;
+
- /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */
- if (i3notes)
- distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL,
-
-From 464f34464d1abdb6e5dfcab0e78e12e15ca133b5 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Mar 2017 16:12:37 +0100
-Subject: [PATCH 040/303] @B added further constraints to optimize the compare
- away
-
----
- gcc/combine.c | 13 ++++++++++---
- 1 file changed, 10 insertions(+), 3 deletions(-)
-
-diff --git a/gcc/combine.c b/gcc/combine.c
-index 333f8fef9655..1103521f9cf1 100644
---- gcc/combine.c
-+++ gcc/combine.c
-@@ -2598,7 +2598,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- I2 and not in I3, a REG_DEAD note must be made. */
- rtx i3dest_killed = 0;
- /* SET_DEST and SET_SRC of I2, I1 and I0. */
-- rtx i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
-+ rtx i3src = 0, i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
- /* Copy of SET_SRC of I1 and I0, if needed. */
- rtx i1src_copy = 0, i0src_copy = 0, i0src_copy2 = 0;
- /* Set if I2DEST was reused as a scratch register. */
-@@ -2632,6 +2632,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- if (i1 == i2 || i0 == i2 || (i0 && i0 == i1))
- return 0;
-
-+ if (single_set(i3))
-+ i3src = SET_SRC(single_set(i3));
-+
- /* Only try four-insn combinations when there's high likelihood of
- success. Look for simple insns, such as loads of constants or
- binary operations involving a constant. */
-@@ -3367,6 +3370,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- * then perform the combine and mark the compare as deleted.
- */
- if (i2dest_killed && !i0 && !i1 && i2pat && i2_is_used + added_sets_2 > 1
-+ && rtx_equal_p(i2dest, i3src)
- && NEXT_INSN(i3))
- {
- rtx_insn *next = NEXT_INSN(i3);
-@@ -3391,7 +3395,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
-
- /* perform deletion later, if all other checks are ok. */
- del4 = next;
-- }
++// printf ("label start check %d use %d\n", pos, bb.is_use (rename_regno) || bb.is_def(rename_regno)); fflush (stdout);
++
++ if (bb.is_use (rename_regno) || bb.is_def (rename_regno))
++ {
++ unsigned start = find_start (pos - 1, rename_regno);
++ todo.insert (start);
++// printf ("label %d : start %d \n", pos, start); fflush (stdout);
+ }
- }
- }
- }
-@@ -4438,10 +4442,13 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- /* SBF: perform the deletion of the next insn, if marked. */
- if (del4)
- {
-+// rtx set = SET_SRC(single_set(del4));
-+
- int del_from_luid = DF_INSN_LUID(del4);
- LOG_LINKS(del4) = NULL;
- REG_NOTES(del4) = 0;
-- SET_INSN_DELETED(del4);
-+ SET_INSN_DELETED(del4);
-+// XEXP(set, 0) = XEXP(set, 1);
- if (newi2pat)
- move_deaths(newi2pat, NULL_RTX, del_from_luid, del4, &midnotes);
- move_deaths(newpat, NULL_RTX, del_from_luid, del4, &midnotes);
-
-From 704efeb80a44bf883699e620c4b51eef32d9659c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 24 Mar 2017 17:05:33 +0100
-Subject: [PATCH 041/303] @N support -ramiga-... stuff
-
----
- gcc/config/m68k/amigaos.opt | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 4d9a42052355..f985cf5e2845 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -7,6 +7,18 @@ noixemul
- Target RejectNegative
- Do not use ixemul.library - use libnix instead to link
-
-+ramiga-lib
-+Target RejectNegative
-+Use libinit.o as start file
++ }
+
-+ramiga-libr
-+Target RejectNegative
-+Use libinitr.o as start file
++ continue;
++ }
+
-+ramiga-dev
-+Target RejectNegative
-+Use devinit.o as start file
++ insn_info & jj = infos[pos];
+
- msmall-code
- Target RejectNegative Var(flag_smallcode,1)
- small code model
-
-From d62a4d349a55a59aa9d8b9a3f02827d66be960b4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 24 Mar 2017 17:06:31 +0100
-Subject: [PATCH 042/303] @R make exception section name configurable by TARGET
-
----
- gcc/config/m68k/m68kamigaos.h | 6 ++++++
- gcc/except.c | 4 ++--
- gcc/target-def.h | 8 ++++++++
- 3 files changed, 16 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 74403a50bb67..ececc6d76498 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -601,3 +601,9 @@ extern int amiga_is_const_pic_ref(const_rtx x);
- ! symbolic_operand (X, VOIDmode) || LEGITIMATE_BASEREL_OPERAND_P (X))
-
- // (GET_CODE(X) == CONST && (GET_CODE(XEXP(X, 0)) == SYMBOL_REF || GET_CODE(XEXP(X, 0)) == LABEL_REF) && !CONSTANT_POOL_ADDRESS_P (XEXP(X, 0))) ||
++ /* marked as hard reg -> invalid rename */
++ if (jj.get_use () & jj.get_hard () & rename_regbit)
++ {
++ mask = 0;
++ break;
++ }
+
-+#undef TARGET_GCC_EXCEPT_TABLE
-+#define TARGET_GCC_EXCEPT_TABLE ".data"
++ /* not used. and not a def */
++ if (pos == runpos && (jj.get_def () & rename_regbit))
++ {
++ /* continue since this pos was added by start search. */
++ }
++ else if (!(jj.get_use () & rename_regbit))
++ break;
+
-+#undef TARGET_GCC_EXCEPT_TABLE_S
-+#define TARGET_GCC_EXCEPT_TABLE_S ".data"
-diff --git a/gcc/except.c b/gcc/except.c
-index 2a1073f80cc4..156d7b76d249 100644
---- gcc/except.c
-+++ gcc/except.c
-@@ -2850,14 +2850,14 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
- it linkonce if we have COMDAT groups to tie them together. */
- if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)
- flags |= SECTION_LINKONCE;
-- sprintf (section_name, ".gcc_except_table.%s", fnname);
-+ sprintf (section_name, TARGET_GCC_EXCEPT_TABLE_S, fnname);
- s = get_section (section_name, flags, current_function_decl);
- free (section_name);
- }
- else
- #endif
- exception_section
-- = s = get_section (".gcc_except_table", flags, NULL);
-+ = s = get_section (TARGET_GCC_EXCEPT_TABLE, flags, NULL);
- }
- else
- exception_section
-diff --git a/gcc/target-def.h b/gcc/target-def.h
-index ec5e09e568e6..9fbfde121095 100644
---- gcc/target-def.h
-+++ gcc/target-def.h
-@@ -108,3 +108,11 @@
- #include "hooks.h"
- #include "targhooks.h"
- #include "insn-target-def.h"
++ /* abort if some insn using this reg uses more than 1 reg. */
++ if ((jj.get_myuse () & rename_regbit) && GET_MODE_SIZE(jj.get_mode()) > 4)
++ {
++ mask = 0;
++ break;
++ }
+
-+#ifndef TARGET_GCC_EXCEPT_TABLE
-+#define TARGET_GCC_EXCEPT_TABLE ".gcc_except_table"
-+#endif
++ /* update free regs. */
++ mask &= ~jj.get_use ();
++ mask &= ~jj.get_def ();
++ if (!mask)
++ break;
+
-+#ifndef TARGET_GCC_EXCEPT_TABLE_S
-+#define TARGET_GCC_EXCEPT_TABLE_S ".gcc_except_table.%s"
-+#endif
-
-From bd6fbbbc0a587184db27e691e05a795e1abdeaf6 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 24 Mar 2017 17:07:18 +0100
-Subject: [PATCH 043/303] @R build libstdc++-v3 with noiexmul
-
----
- libstdc++-v3/configure | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
-index 44ba3aca42af..d61b41b2fb7c 100755
---- libstdc++-v3/configure
-+++ libstdc++-v3/configure
-@@ -8636,6 +8636,8 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ enable_shared=no
-+ CXXFLAGS="$CXXFLAGS -noixemul"
- ;;
- esac
- ;;
-
-From f05e1e6bd5a30ee7dfea2399acf268771c986767 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 25 Mar 2017 23:11:55 +0100
-Subject: [PATCH 044/303] @R move all EH data into .text section
-
----
- gcc/config/m68k/m68kamigaos.h | 7 +++++--
- gcc/dwarf2out.c | 2 +-
- 2 files changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index ececc6d76498..68f3277bd87c 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -603,7 +603,10 @@ extern int amiga_is_const_pic_ref(const_rtx x);
- // (GET_CODE(X) == CONST && (GET_CODE(XEXP(X, 0)) == SYMBOL_REF || GET_CODE(XEXP(X, 0)) == LABEL_REF) && !CONSTANT_POOL_ADDRESS_P (XEXP(X, 0))) ||
-
- #undef TARGET_GCC_EXCEPT_TABLE
--#define TARGET_GCC_EXCEPT_TABLE ".data"
-+#define TARGET_GCC_EXCEPT_TABLE ".text"
-
- #undef TARGET_GCC_EXCEPT_TABLE_S
--#define TARGET_GCC_EXCEPT_TABLE_S ".data"
-+#define TARGET_GCC_EXCEPT_TABLE_S ".text"
++ found.insert (pos);
+
-+#define EH_TABLES_CAN_BE_READ_ONLY 1
++ /* follow jump and/or next insn. */
++ if (JUMP_P(insn))
++ {
++ for (j2l_iterator i = jump2label.find (pos), k = i; i != jump2label.end () && i->first == k->first;
++ ++i)
++ {
++ unsigned label_index = i->second;
+
-diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
-index 995ae7f18758..2740e417b0b2 100644
---- gcc/dwarf2out.c
-+++ gcc/dwarf2out.c
-@@ -451,7 +451,7 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
- /*global=*/1);
- lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,
- /*global=*/0);
-- flags = ((! flag_pic
-+ flags = (( (!flag_pic || flag_pic > 2)
- || ((fde_encoding & 0x70) != DW_EH_PE_absptr
- && (fde_encoding & 0x70) != DW_EH_PE_aligned
- && (per_encoding & 0x70) != DW_EH_PE_absptr
-
-From 3be02d432149821fde6d3de2eca3830943c9dfc1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 26 Mar 2017 20:49:43 +0200
-Subject: [PATCH 045/303] @R patches to work with amigaos-*-m68k
-
----
- libstdc++-v3/configure.host | 5 +++++
- libstdc++-v3/include/c_global/cstdio | 2 --
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
-index 304a7f5aff61..354b1c7ead46 100644
---- libstdc++-v3/configure.host
-+++ libstdc++-v3/configure.host
-@@ -226,6 +226,11 @@ case "${host_os}" in
- os_include_dir="os/generic"
- atomicity_dir="cpu/generic"
- ;;
-+ amiga*)
-+ os_include_dir="os/newlib"
-+ CXXFLAGS="${CXXFLAGS} -noixemul"
-+ CPPFLAGS="${CPPFLAGS} -noixemul"
-+ ;;
- bsd*)
- # Plain BSD attempts to share FreeBSD files.
- os_include_dir="os/bsd/freebsd"
-diff --git a/libstdc++-v3/include/c_global/cstdio b/libstdc++-v3/include/c_global/cstdio
-index 522d065d4dc6..86d524f96a62 100644
---- libstdc++-v3/include/c_global/cstdio
-+++ libstdc++-v3/include/c_global/cstdio
-@@ -149,9 +149,7 @@ namespace std
- #if _GLIBCXX_USE_C99_STDIO
-
- #undef snprintf
--#ifndef AMIGA
- #undef vfscanf
--#endif
- #undef vscanf
- #undef vsnprintf
- #undef vsscanf
-
-From 1a1c3869ddd0e8e75eef0849dcd0b060dd26cbbd Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 26 Mar 2017 20:50:20 +0200
-Subject: [PATCH 046/303] @R patches to work with amigaos-*-m68k
-
----
- libobjc/configure | 3 ++-
- libobjc/objc/objc.h | 4 ++++
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/libobjc/configure b/libobjc/configure
-index 55fcc33dbe2d..a60258f422d8 100755
---- libobjc/configure
-+++ libobjc/configure
-@@ -7637,7 +7637,8 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
-- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ #lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ enable_shared=no
- ;;
- esac
- ;;
-diff --git a/libobjc/objc/objc.h b/libobjc/objc/objc.h
-index 37391a446bb0..6c73f53290e8 100644
---- libobjc/objc/objc.h
-+++ libobjc/objc/objc.h
-@@ -52,7 +52,11 @@ extern "C" {
- Important: this could change and we could switch to 'typedef bool
- BOOL' in the future. Do not depend on the type of BOOL. */
- #undef BOOL
-+#ifdef AMIGA
-+typedef short BOOL;
-+#else
- typedef unsigned char BOOL;
-+#endif
-
- #define YES (BOOL)1
- #define NO (BOOL)0
-
-From 7f8948f412f79fb2efd6835a3062720c1b34febf Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 29 Mar 2017 18:08:05 +0200
-Subject: [PATCH 047/303] @B fix for possible corrupted code, due to combine
- optimization. Maybe incorrect...
-
----
- gcc/reload1.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/reload1.c b/gcc/reload1.c
-index c2800f8cb790..7f386a3aaab0 100644
---- gcc/reload1.c
-+++ gcc/reload1.c
-@@ -7943,7 +7943,8 @@ do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
- AUTO_INC reload if reload_out is set but reload_out_reg isn't. */
- && (! reload_inherited[j] || (rl->out && ! rl->out_reg))
- && ! rtx_equal_p (reg_rtx, old)
-- && reg_rtx != 0)
-+ && reg_rtx != 0
-+ && rl->in_reg != rl->out_reg)
- emit_input_reload_insns (chain, rld + j, old, j);
-
- /* When inheriting a wider reload, we have a MEM in rl->in,
-
-From 709da5eaf06c7d9d1aa3332feab227469be4cc48 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 30 Mar 2017 11:29:16 +0200
-Subject: [PATCH 048/303] @B remove optimization The side effects are not
- solved yet, so this experiment is removed from the 'stable' branch
-
----
- gcc/combine.c | 69 +----------------------------------------------------------
- gcc/reload1.c | 3 +--
- 2 files changed, 2 insertions(+), 70 deletions(-)
-
-diff --git a/gcc/combine.c b/gcc/combine.c
-index 1103521f9cf1..75c6229766c0 100644
---- gcc/combine.c
-+++ gcc/combine.c
-@@ -102,7 +102,6 @@ along with GCC; see the file COPYING3. If not see
- #include "valtrack.h"
- #include "rtl-iter.h"
- #include "print-rtl.h"
--#include "conditions.h"
-
- #ifndef LOAD_EXTEND_OP
- #define LOAD_EXTEND_OP(M) UNKNOWN
-@@ -2579,7 +2578,6 @@ static rtx_insn *
- try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- int *new_direct_jump_p, rtx_insn *last_combined_insn)
- {
-- rtx_insn * del4 = 0;
- /* New patterns for I3 and I2, respectively. */
- rtx newpat, newi2pat = 0;
- rtvec newpat_vec_with_clobbers = 0;
-@@ -2598,7 +2596,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- I2 and not in I3, a REG_DEAD note must be made. */
- rtx i3dest_killed = 0;
- /* SET_DEST and SET_SRC of I2, I1 and I0. */
-- rtx i3src = 0, i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
-+ rtx i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
- /* Copy of SET_SRC of I1 and I0, if needed. */
- rtx i1src_copy = 0, i0src_copy = 0, i0src_copy2 = 0;
- /* Set if I2DEST was reused as a scratch register. */
-@@ -2632,9 +2630,6 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- if (i1 == i2 || i0 == i2 || (i0 && i0 == i1))
- return 0;
-
-- if (single_set(i3))
-- i3src = SET_SRC(single_set(i3));
--
- /* Only try four-insn combinations when there's high likelihood of
- success. Look for simple insns, such as loads of constants or
- binary operations involving a constant. */
-@@ -3355,53 +3350,6 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- substed_i0 = 1;
- }
-
--#if HAVE_cc0
-- /* SBF: This is an attempt to combine
-- * i2 something -> reg
-- * i3 reg -> somewhere
-- * with the next insn i4
-- * i4 compare reg, 0
-- *
-- * then
-- * newpat = something -> somewhere
-- *
-- * If the comparison with 0 is already done in the insn newpat
-- * and the reg is dead at the compare insn
-- * then perform the combine and mark the compare as deleted.
-- */
-- if (i2dest_killed && !i0 && !i1 && i2pat && i2_is_used + added_sets_2 > 1
-- && rtx_equal_p(i2dest, i3src)
-- && NEXT_INSN(i3))
-- {
-- rtx_insn *next = NEXT_INSN(i3);
-- rtx setn = single_set(next);
-- if (setn)
-- {
-- rtx srcn = SET_SRC(setn);
-- if (GET_CODE(srcn) == COMPARE)
-- {
-- rtx dstn = XEXP(srcn, 0);
-- srcn = XEXP(srcn, 1);
--
-- if (CONST_INT_P(srcn) && INTVAL(srcn) == 0
-- && find_reg_note(next, REG_DEAD, dstn))
-- {
-- /* now check via NOTICE_UPDATE_CC*/
-- NOTICE_UPDATE_CC(PATTERN(i2), i2);
-- if (cc_status.flags == 0 && rtx_equal_p(dstn, cc_status.value1))
-- {
-- added_sets_2 = 0;
-- i2_is_used = 0;
--
-- /* perform deletion later, if all other checks are ok. */
-- del4 = next;
-- }
-- }
-- }
-- }
-- }
--#endif
--
- /* Fail if an autoincrement side-effect has been duplicated. Be careful
- to count all the ways that I2SRC and I1SRC can be used. */
- if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0
-@@ -4439,21 +4387,6 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
- move_deaths (newi2pat, NULL_RTX, from_luid, i2, &midnotes);
- move_deaths (newpat, newi2pat, from_luid, i3, &midnotes);
-
-- /* SBF: perform the deletion of the next insn, if marked. */
-- if (del4)
-- {
--// rtx set = SET_SRC(single_set(del4));
--
-- int del_from_luid = DF_INSN_LUID(del4);
-- LOG_LINKS(del4) = NULL;
-- REG_NOTES(del4) = 0;
-- SET_INSN_DELETED(del4);
--// XEXP(set, 0) = XEXP(set, 1);
-- if (newi2pat)
-- move_deaths(newi2pat, NULL_RTX, del_from_luid, del4, &midnotes);
-- move_deaths(newpat, NULL_RTX, del_from_luid, del4, &midnotes);
-- }
--
- /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */
- if (i3notes)
- distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL,
-diff --git a/gcc/reload1.c b/gcc/reload1.c
-index 7f386a3aaab0..c2800f8cb790 100644
---- gcc/reload1.c
-+++ gcc/reload1.c
-@@ -7943,8 +7943,7 @@ do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
- AUTO_INC reload if reload_out is set but reload_out_reg isn't. */
- && (! reload_inherited[j] || (rl->out && ! rl->out_reg))
- && ! rtx_equal_p (reg_rtx, old)
-- && reg_rtx != 0
-- && rl->in_reg != rl->out_reg)
-+ && reg_rtx != 0)
- emit_input_reload_insns (chain, rld + j, old, j);
-
- /* When inheriting a wider reload, we have a MEM in rl->in,
-
-From c44d7bced301829dbab55b307545a7e029e69e6f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 30 Mar 2017 20:44:57 +0200
-Subject: [PATCH 049/303] @N added a separate optimization pass
-
----
- gcc/Makefile.in | 1 +
- gcc/bbb-opts.c | 401 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- gcc/passes.c | 27 ++++
- gcc/passes.def | 1 +
- gcc/regrename.c | 9 +-
- gcc/tree-pass.h | 1 +
- 6 files changed, 437 insertions(+), 3 deletions(-)
- create mode 100755 gcc/bbb-opts.c
- mode change 100644 => 100755 gcc/regrename.c
-
-diff --git a/gcc/Makefile.in b/gcc/Makefile.in
-index 575d308907cc..dc01aeef0f0c 100644
---- gcc/Makefile.in
-+++ gcc/Makefile.in
-@@ -1199,6 +1199,7 @@ OBJS = \
- auto-inc-dec.o \
- auto-profile.o \
- bb-reorder.o \
-+ bbb-opts.o \
- bitmap.o \
- bt-load.o \
- builtins.o \
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-new file mode 100755
-index 000000000000..ff447c9e335e
---- /dev/null
-+++ gcc/bbb-opts.c
-@@ -0,0 +1,401 @@
-+/* Bebbo's Optimizations.
-+ Copyright (C) 2010-2016 Free Software Foundation, Inc.
++ /* add the label to the search list. */
++ insn_info & bb = infos[label_index + 1];
++ if (found.find (label_index) == found.end () && bb.is_use (rename_regno))
++ {
++// printf ("jump %d -> label %d \n", pos, label_index); fflush (stdout);
++ todo.insert (label_index);
++ }
++ }
++ rtx set = single_set (insn);
++ if (!set)
++ {
++ // it's a parallel pattern - search the set pc = ...
++ rtx pat = PATTERN (insn);
++ for (int j = XVECLEN (pat, 0) - 1; j >= 0; j--)
++ {
++ rtx x = XVECEXP(pat, 0, j);
++ if (XEXP(x, 0) == pc_rtx)
++ {
++ set = x;
++ break;
++ }
++ }
++ }
++ rtx jmpsrc = set ? SET_SRC(set) : 0;
++ if (!jmpsrc || GET_CODE(jmpsrc) != IF_THEN_ELSE)
++ break;
++ }
++ }
++ }
+
-+ This file is part of GCC.
++ if (mask)
++ {
++ int oldregno = bit2regno (rename_regbit);
++ int newregno = bit2regno (mask);
+
-+ 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 3, or (at your option) any later
-+ version.
++ /* check the renamed insns. */
++ std::vector<unsigned> positions;
++ for (std::set<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
++ {
++ insn_info & rr = infos[*i];
++ rtx_insn * insn = rr.get_insn ();
+
-+ 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.
++ /* get rename locations. */
++ rtx from = find_reg_by_no (PATTERN (insn), oldregno);
++ if (from)
++ {
++ rtx to = gen_raw_REG (GET_MODE(from), newregno);
++ validate_replace_rtx_group (from, to, insn);
+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <http://www.gnu.org/licenses/>. */
++ positions.push_back (*i);
++ }
++ }
+
-+/**
-+ * SBF (Stefan "Bebbo" Franke):
-+ *
-+ * This pass performs multiple optimizations.
-+ *
-+ * #1 propagate_moves
-+ * check if a->b->a can be moved out of a loop.
-+ *
-+ * #2 strcpy
-+ * move a,reg
-+ * move reg,b
-+ * cmp #0,reg
-+ * jne/jeq
-+ */
++ if (!apply_change_group ())
++ continue;
+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "backend.h"
-+#include "target.h"
-+#include "rtl.h"
-+#include "df.h"
-+#include "tm_p.h"
-+#include "insn-config.h"
-+#include "recog.h"
-+#include "cfgrtl.h"
-+#include "emit-rtl.h"
-+#include "tree-pass.h"
-+#include "conditions.h"
-+#include <vector>
-+#include <map>
++ log ("(r) opt_reg_rename %s -> %s (%d locs, start at %d)\n", reg_names[oldregno], reg_names[newregno],
++ positions.size (), index);
+
-+extern void
-+dump_insns (char const * name);
++ if (be_verbose)
++ {
++ for (std::vector<unsigned>::iterator i = positions.begin (); i != positions.end (); ++i)
++ printf ("%d ", *i);
++ printf ("\n");
++ fflush (stdout);
++ }
++
++ return 1;
++ }
++ }
++ return 0;
++}
+
+/*
+ * #1 propagate a->b->a moves out of a loop.
@@ -6875,30 +3363,34 @@ index 000000000000..ff447c9e335e
+ move.b d1,(a0)+
+ cmp.b #0, d1
+ jne .L6
++
+ *
++ * Also allow exit jumps, if the modification of the reg is const
++ * and insert a correction after the exit label.
++ * The label must only be reachable by the exit jump.
+ */
-+static int
-+propagate_moves ()
++static unsigned
++opt_propagate_moves ()
+{
-+ rtx_insn *insn, *next;
++ unsigned change_count = 0;
+ rtx_insn * current_label = 0;
-+ int change_count = 0;
-+ std
-+ ::vector<rtx_insn *> reg_reg;
++ unsigned current_label_index;
++ std::vector<unsigned> reg_reg;
++ std::vector<rtx_insn *> jump_out;
+
-+ for (insn = get_insns (); insn; insn = next)
++ /* start at 1 since there must be an insn before the label. */
++ for (unsigned index = 1; index < infos.size (); ++index)
+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (DEBUG_INSN_P(insn))
-+ continue;
++ rtx_insn * insn = infos[index].get_insn ();
+
+ if (LABEL_P(insn))
+ {
+ if (LABEL_NUSES(insn) == 1)
+ {
+ current_label = insn;
++ current_label_index = index;
+ reg_reg.clear ();
++ jump_out.clear ();
+ }
+ else
+ current_label = 0;
@@ -6916,58 +3408,186 @@ index 000000000000..ff447c9e335e
+ rtx src = SET_SRC(set);
+ rtx dst = SET_DEST(set);
+ if (REG_P(src) && REG_P(dst))
-+ reg_reg.push_back (insn);
++ reg_reg.push_back (index);
+ }
++ else
++ current_label = 0;
++
+ continue;
+ }
+
+ if (JUMP_P(insn))
+ {
-+ if (JUMP_LABEL (insn) == current_label && reg_reg.size () > 1)
++ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
++ if (label != current_label)
++ {
++ /* collect the labels for a later check if a fixup is possible. */
++ if (LABEL_NUSES(label) == 1 && BARRIER_P(PREV_INSN (label)))
++ jump_out.push_back (label);
++ else
++ current_label = 0;
++ continue;
++ }
++
++ if (reg_reg.size () > 1)
+ {
+ /* Search for reg/reg pairs. */
-+ for (auto i = reg_reg.begin ();
-+ i != reg_reg.end () && i + 1 != reg_reg.end ();)
++ for (std::vector<unsigned>::iterator i = reg_reg.begin (); i != reg_reg.end () && i + 1 != reg_reg.end ();
++ )
+ {
+ bool inc = true;
-+ for (auto j = i + 1; j != reg_reg.end ();)
++ for (std::vector<unsigned>::iterator j = i + 1; j != reg_reg.end ();)
+ {
-+ rtx seti = single_set (*i);
++ rtx_insn * ii = infos[*i].get_insn ();
++ rtx seti = single_set (ii);
+ rtx srci = SET_SRC(seti);
+ rtx dsti = SET_DEST(seti);
-+ rtx setj = single_set (*j);
++ rtx_insn * jj = infos[*j].get_insn ();
++ rtx setj = single_set (jj);
+ rtx srcj = SET_SRC(setj);
+ rtx dstj = SET_DEST(setj);
+
+ if (rtx_equal_p (srci, dstj) && rtx_equal_p (srcj, dsti))
+ {
+ /* Ensure correct usage. */
-+ if (!reg_used_between_p (srci, current_label, *i)
-+ && !reg_used_between_p (srci, *i, *j)
-+ && !reg_used_between_p (srci, *j, insn)
-+ && !reg_used_between_p (dsti, current_label, *i)
-+ && !reg_used_between_p (dsti, *j, insn))
++ if (is_reg_touched_between (REGNO(srci), current_label_index, *i) // label ... move src,x
++ || is_reg_touched_between (REGNO(srci), *i, *j) // move src,x ... move x,src
++ || is_reg_touched_between (REGNO(srci), *j, index) // move x,src ... jcc
++ || is_reg_touched_between (REGNO(dsti), *j, index) // label ... move src,x
++ || is_reg_touched_between (REGNO(dsti), *j, index) // move x,src ... jcc
++ )
++ {
++ ++j;
++ continue;
++ }
++
++ std::vector<int> fixups;
++
++ /* if there are jumps out of the loop,
++ * check if the modification occurs before the jump,
++ * and if, that it's a plus const.
++ */
++ if (jump_out.size ())
+ {
-+ fprintf (stderr,
-+ "condition met, moving regs %d, %d\n",
-+ REGNO(srci), REGNO(dsti));
-+
-+ /* Move out of loop. */
-+ remove_insn (*i);
-+ if (PREV_INSN (current_label))
-+ add_insn_after (*i, PREV_INSN (current_label),
-+ 0);
++ std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
++ int fixup = 0;
++
++ for (unsigned k = *i + 1; k != *j; ++k)
++ {
++ rtx_insn * check = infos[k].get_insn ();
++ if (JUMP_P(check))
++ {
++ fixups.push_back (fixup);
++ if (++label_iter == jump_out.end ())
++ break;
++ continue;
++ }
++
++ if (reg_overlap_mentioned_p (dsti, PATTERN (check)))
++ {
++ /* right now only support auto_incs. */
++ rtx set = single_set (check);
++ rtx src = SET_SRC(set);
++ rtx dst = SET_DEST(set);
++
++ if (reg_overlap_mentioned_p (dsti, dst))
++ {
++ if (REG_P(dst))
++ break;
++ if (!MEM_P(dst))
++ break;
++
++ rtx x = XEXP(dst, 0);
++ if (GET_CODE(x) == REG)
++ fixup += 0; // direct use
++ else if (GET_CODE(x) == PRE_INC ||
++ GET_CODE(x) == POST_INC)
++ fixup -= GET_MODE_SIZE(GET_MODE(dst));
++ else if (GET_CODE(dst) == PRE_DEC ||
++ GET_CODE(dst) == POST_DEC)
++ fixup += GET_MODE_SIZE(GET_MODE(dst));
++ else
++ break;
++ }
++
++ if (reg_overlap_mentioned_p (dsti, src))
++ {
++ if (REG_P(src))
++ fixup += 0;
++ else
++ {
++ if (!MEM_P(src))
++ break;
++
++ rtx x = XEXP(src, 0);
++ if (GET_CODE(x) == REG)
++ fixup += 0; // direct use
++ else if (GET_CODE(x) == PRE_INC ||
++ GET_CODE(x) == POST_INC)
++ fixup -= GET_MODE_SIZE(GET_MODE(dst));
++ else if (GET_CODE(dst) == PRE_DEC ||
++ GET_CODE(dst) == POST_DEC)
++ fixup += GET_MODE_SIZE(GET_MODE(dst));
++ else
++ break;
++ }
++ }
++ }
++ }
++ }
++
++ /* got a fixup for all jump_outs? */
++ if (fixups.size () == jump_out.size ())
++ {
++ rtx_insn * before = infos[current_label_index - 1].get_insn ();
++ rtx_insn * after = infos[index + 1].get_insn ();
++ rtx bset = single_set (before);
++
++ log ("(p) propagate_moves condition met, moving regs %s, %s\n",
++ reg_names[REGNO(srci)],
++ reg_names[REGNO(dsti)]);
++
++ /* Move in front of loop and mark as dead. */
++ rtx_insn * newii = make_insn_raw (PATTERN (ii));
++ SET_INSN_DELETED(ii);
++
++ /* Plus check if the reg was just loaded. */
++ if (bset)
++ {
++ rtx bdst = SET_DEST(bset);
++ if (REG_P(bdst) && REGNO(bdst) == REGNO(srci))
++ {
++ SET_SRC(PATTERN(newii)) = SET_SRC(bset);
++// SET_INSN_DELETED(ii);
++ }
++ }
+ else
-+ add_insn_before (*i, current_label, 0);
++ add_reg_note (newii, REG_DEAD, srci);
++
++ add_insn_after (newii, before, 0);
+
-+ remove_insn (*j);
-+ add_insn_after (*j, insn, 0);
++ /* Move behind loop - into next BB. */
++ rtx_insn * newjj = make_insn_raw (PATTERN (jj));
++ add_insn_before (newjj, after, 0);
++ SET_INSN_DELETED(jj);
+
+ reg_reg.erase (j);
+ reg_reg.erase (i);
+ j = reg_reg.end ();
+ inc = false;
+
++ /* add fixes if there were jumps out of the loop. */
++ if (jump_out.size ())
++ {
++ log ("(p) propagate_moves fixing %d jump outs\n", jump_out.size ());
++
++ for (unsigned k = 0; k < jump_out.size (); ++k)
++ {
++ rtx neu = gen_rtx_SET(
++ dstj, gen_rtx_PLUS (Pmode, dsti, gen_rtx_CONST_INT (Pmode, fixups[k])));
++ emit_insn_after (neu, jump_out[k]);
++ }
++ }
+ ++change_count;
+ }
+ }
@@ -6981,7 +3601,6 @@ index 000000000000..ff447c9e335e
+ current_label = 0;
+ }
+ }
-+
+ return change_count;
+}
+
@@ -6997,1385 +3616,98 @@ index 000000000000..ff447c9e335e
+ *
+ * Use a simple state machine to find the patterns.
+ */
-+static void
++static unsigned
+opt_strcpy ()
+{
-+ rtx_insn *insn, *next;
++ unsigned change_count = 0;
++#if HAVE_cc0
+ rtx_insn * x2reg = 0;
+ rtx_insn * reg2x;
+ unsigned int regno;
+
-+ for (insn = get_insns (); insn; insn = next)
++ for (unsigned index = 0; index < infos.size (); ++index)
+ {
-+ rtx src;
-+
-+ next = NEXT_INSN (insn);
-+
-+ if (NONJUMP_INSN_P(insn))
-+ {
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ if (x2reg && reg2x)
-+ {
-+ src = SET_SRC(set);
-+ if (GET_CODE(src) == COMPARE)
-+ {
-+ rtx dst = XEXP(src, 0);
-+ src = XEXP(src, 1);
-+
-+ if (CONST_INT_P(src) && INTVAL(src) == 0
-+ && find_reg_note (insn, REG_DEAD, dst))
-+ {
-+ /* now check via NOTICE_UPDATE_CC*/
-+ NOTICE_UPDATE_CC (PATTERN (reg2x), reg2x);
-+ if (cc_status.flags == 0
-+ && rtx_equal_p (dst, cc_status.value2))
-+ {
-+ int num_clobbers_to_add = 0;
-+ int insn_code_number;
-+
-+ SET_SRC(single_set(reg2x)) = SET_SRC(
-+ single_set (x2reg));
-+ insn_code_number = recog (PATTERN (reg2x), reg2x,
-+ &num_clobbers_to_add);
-+
-+ if (insn_code_number < 0)
-+ {
-+ /* restore register. */
-+ SET_SRC(single_set(reg2x)) = SET_DEST(
-+ single_set (x2reg));
-+ }
-+ else
-+ {
-+
-+ rtx link;
-+
-+ fprintf (
-+ stderr,
-+ "condition met, removing compare and joining insns - omit reg %d\n",
-+ REGNO(dst));
-+
-+ for (link = REG_NOTES(x2reg); link;
-+ link = XEXP(link, 1))
-+ if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
-+ {
-+ if (GET_CODE (link) == EXPR_LIST)
-+ add_reg_note (
-+ reg2x, REG_NOTE_KIND(link),
-+ copy_insn_1 (XEXP(link, 0)));
-+ else
-+ add_shallow_copy_of_reg_note (reg2x,
-+ link);
-+ }
-+
-+ SET_INSN_DELETED(x2reg);
-+ SET_INSN_DELETED(insn);
-+
-+ df_insn_rescan (reg2x);
-+
-+ }
-+ }
-+ }
-+ x2reg = 0;
-+ continue;
-+ }
-+ reg2x = 0;
-+ }
-+
-+ /* check for reg2x first, maybe fallback to x2reg. */
-+ if (x2reg && reg2x == 0)
-+ {
-+ if (REG_P(SET_SRC(set)) && REGNO(SET_SRC(set)) == regno)
-+ {
-+ reg2x = insn;
-+ continue;
-+ }
-+ x2reg = 0;
-+ }
-+
-+ /* check for a match for x2reg. */
-+ if (x2reg == 0)
-+ {
-+ if (REG_P(SET_DEST(set)))
-+ {
-+ x2reg = insn;
-+ reg2x = 0;
-+ regno = REGNO(SET_DEST(set));
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+/* Main entry point to the pass. */
-+
-+static unsigned int
-+execute_bbb_optimizations (void)
-+{
-+ df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
-+ df_note_add_problem ();
-+ df_analyze ();
-+
-+// dump_insns ("bbb 0");
-+
-+ propagate_moves ();
-+
-+ opt_strcpy ();
-+
-+ dump_insns ("bbb 1");
-+
-+ return 0;
-+}
-+
-+namespace
-+ {
-+
-+ const pass_data pass_data_bbb_optimizations =
-+ {
-+ RTL_PASS, /* type */
-+ "bbb", /* name */
-+ OPTGROUP_NONE, /* optinfo_flags */
-+ TV_NONE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ ( TODO_df_finish | TODO_df_verify ), /* todo_flags_finish */
-+ };
-+
-+ class pass_bbb_optimizations : public rtl_opt_pass
-+ {
-+ public:
-+ pass_bbb_optimizations (gcc::context *ctxt)
-+ : rtl_opt_pass (pass_data_bbb_optimizations, ctxt)
-+ {}
-+
-+ /* opt_pass methods: */
-+ virtual bool gate (function *)
-+ {
-+ return true;
-+ }
-+
-+ virtual unsigned int execute (function *)
-+ {
-+ return execute_bbb_optimizations ();
-+ }
-+
-+ }; // class pass_bbb_optimizations
-+
-+ } // anon namespace
++ rtx_insn * insn = infos[index].get_insn ();
+
-+rtl_opt_pass *
-+make_pass_bbb_optimizations (gcc::context *ctxt)
-+ {
-+ return new pass_bbb_optimizations (ctxt);
-+ }
-diff --git a/gcc/passes.c b/gcc/passes.c
-index e89618111245..321adbc61e2d 100644
---- gcc/passes.c
-+++ gcc/passes.c
-@@ -2269,6 +2269,31 @@ override_gate_status (opt_pass *pass, tree func, bool gate_status)
- }
-
-
-+void dump_insns(char const * name)
-+{
-+ rtx_insn *insn, *next;
-+ fprintf(stderr, "====================================\npass: %s\n", name);
-+ for (insn = get_insns(); insn; insn = next)
-+ {
-+ next = NEXT_INSN(insn);
-+ debug_rtx(insn);
-+#if 0
-+ if (NONJUMP_INSN_P (insn))
++ if (!NONJUMP_INSN_P(insn))
+ {
-+ rtx x, y, set= single_set (insn);
-+ if (!set)
-+ continue;
-+ x = y = SET_SRC(set);
-+
-+ while (GET_CODE(y) == CONST || GET_CODE(y) == PLUS)
-+ y = XEXP(y, 0);
-+ if (x != y && REG_P(y) && REGNO(y) == PIC_REG)
-+ debug_rtx(insn);
++ x2reg = 0;
++ continue;
+ }
-+#endif
-+ }
-+}
-+
- /* Execute PASS. */
-
- bool
-@@ -2278,6 +2303,8 @@ execute_one_pass (opt_pass *pass)
-
- bool gate_status;
-
-+// dump_insns(pass->name);
+
- /* IPA passes are executed on whole program, so cfun should be NULL.
- Other passes need function context set. */
- if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
-diff --git a/gcc/passes.def b/gcc/passes.def
-index ec796082ae7f..45ff86c383e4 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -446,6 +446,7 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_split_after_reload);
- NEXT_PASS (pass_ree);
- NEXT_PASS (pass_compare_elim_after_reload);
-+ NEXT_PASS (pass_bbb_optimizations);
- NEXT_PASS (pass_branch_target_load_optimize1);
- NEXT_PASS (pass_jump2);
- NEXT_PASS (pass_duplicate_computed_gotos);
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-old mode 100644
-new mode 100755
-index 2dd96db5b87f..4ba825e8d8e8
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -358,6 +358,7 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- enum reg_class preferred_class;
- int best_new_reg = old_reg;
- int new_reg;
-+ int hit = 0;
-
- /* Further narrow the set of registers we can use for renaming.
- If the chain needs a call-saved register, mark the call-used
-@@ -404,9 +405,11 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- don't belong to PREFERRED_CLASS to registers that do, even
- though the latters were used not very long ago.
- Also use a register if no best_new_reg was found till now */
-- if ((tick[best_new_reg] > tick[new_reg]
-- || (old_reg == best_new_reg && new_reg < old_reg)))
-- best_new_reg = new_reg;
-+ if (new_reg < old_reg || !hit)
++ rtx set = single_set (insn);
++ if (!set)
+ {
-+ hit = 1;
-+ best_new_reg = new_reg;
++ x2reg = 0;
++ continue;
+ }
- }
- return best_new_reg;
- }
-diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
-index 5f5055d3a6c1..b3f66ad529b9 100644
---- gcc/tree-pass.h
-+++ gcc/tree-pass.h
-@@ -590,6 +590,7 @@ extern rtl_opt_pass *make_pass_branch_target_load_optimize2 (gcc::context
- *ctxt);
- extern rtl_opt_pass *make_pass_leaf_regs (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_split_before_sched2 (gcc::context *ctxt);
-+extern rtl_opt_pass *make_pass_bbb_optimizations (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_compare_elim_after_reload (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_sched2 (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_stack_regs (gcc::context *ctxt);
-
-From eb051946c1a720575b80bcd5cf8038710f1c27c1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 31 Mar 2017 11:19:56 +0200
-Subject: [PATCH 050/303] @B compiles again with other targets
-
----
- gcc/bbb-opts.c | 205 ++++++++++++++++++++++++++++++++++-----------------------
- gcc/except.c | 1 +
- 2 files changed, 124 insertions(+), 82 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index ff447c9e335e..aeec7a8b4e6a 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -107,11 +107,10 @@ dump_insns (char const * name);
- static int
- propagate_moves ()
- {
-+ int change_count = 0;
- rtx_insn *insn, *next;
- rtx_insn * current_label = 0;
-- int change_count = 0;
-- std
-- ::vector<rtx_insn *> reg_reg;
-+ std::vector<rtx_insn *> reg_reg;
-
- for (insn = get_insns (); insn; insn = next)
- {
-@@ -153,11 +152,11 @@ propagate_moves ()
- if (JUMP_LABEL (insn) == current_label && reg_reg.size () > 1)
- {
- /* Search for reg/reg pairs. */
-- for (auto i = reg_reg.begin ();
-+ for (std::vector<rtx_insn *>::iterator i = reg_reg.begin ();
- i != reg_reg.end () && i + 1 != reg_reg.end ();)
- {
- bool inc = true;
-- for (auto j = i + 1; j != reg_reg.end ();)
-+ for (std::vector<rtx_insn *>::iterator j = i + 1; j != reg_reg.end ();)
- {
- rtx seti = single_set (*i);
- rtx srci = SET_SRC(seti);
-@@ -208,7 +207,6 @@ propagate_moves ()
- current_label = 0;
- }
- }
--
- return change_count;
- }
-
-@@ -224,9 +222,11 @@ propagate_moves ()
- *
- * Use a simple state machine to find the patterns.
- */
--static void
-+static int
- opt_strcpy ()
- {
-+ int change_count = 0;
-+#if HAVE_cc0
- rtx_insn *insn, *next;
- rtx_insn * x2reg = 0;
- rtx_insn * reg2x;
-@@ -234,106 +234,145 @@ opt_strcpy ()
-
- for (insn = get_insns (); insn; insn = next)
- {
-- rtx src;
--
- next = NEXT_INSN (insn);
-
-- if (NONJUMP_INSN_P(insn))
-- {
-- rtx set = single_set (insn);
-- if (!set)
-- continue;
-+ if (!NONJUMP_INSN_P(insn))
-+ continue;
+
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-
-- if (x2reg && reg2x)
+ if (x2reg && reg2x)
+ {
+ rtx src = SET_SRC(set);
+ if (GET_CODE(src) == COMPARE)
- {
-- src = SET_SRC(set);
-- if (GET_CODE(src) == COMPARE)
-- {
-- rtx dst = XEXP(src, 0);
-- src = XEXP(src, 1);
++ {
+ rtx dst = XEXP(src, 0);
+ src = XEXP(src, 1);
-
-- if (CONST_INT_P(src) && INTVAL(src) == 0
-- && find_reg_note (insn, REG_DEAD, dst))
-+ if (CONST_INT_P(src) && INTVAL(src) == 0
-+ && find_reg_note (insn, REG_DEAD, dst))
++
++// if (CONST_INT_P(src) && INTVAL(src) == 0 && find_reg_note (insn, REG_DEAD, dst))
++ if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 && is_reg_dead (REGNO(dst), index))
+ {
+ /* now check via NOTICE_UPDATE_CC*/
-+ NOTICE_UPDATE_CC (PATTERN (reg2x), reg2x);
-+ if (cc_status.flags == 0
-+ && rtx_equal_p (dst, cc_status.value2))
- {
-- /* now check via NOTICE_UPDATE_CC*/
-- NOTICE_UPDATE_CC (PATTERN (reg2x), reg2x);
-- if (cc_status.flags == 0
-- && rtx_equal_p (dst, cc_status.value2))
-- {
-- int num_clobbers_to_add = 0;
-- int insn_code_number;
-+ int num_clobbers_to_add = 0;
-+ int insn_code_number;
-
-- SET_SRC(single_set(reg2x)) = SET_SRC(
-- single_set (x2reg));
-- insn_code_number = recog (PATTERN (reg2x), reg2x,
-- &num_clobbers_to_add);
-+ SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
-+ insn_code_number = recog (PATTERN (reg2x), reg2x,
-+ &num_clobbers_to_add);
-
-- if (insn_code_number < 0)
-- {
-- /* restore register. */
-- SET_SRC(single_set(reg2x)) = SET_DEST(
-- single_set (x2reg));
-- }
-- else
-- {
-+ if (insn_code_number < 0)
-+ {
-+ /* restore register. */
-+ SET_SRC(single_set(reg2x)) = SET_DEST(
-+ single_set (x2reg));
-+ }
-+ else
++ NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
++ if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2))
++ {
++ rtx pattern = gen_rtx_SET(SET_DEST(single_set (reg2x)), SET_SRC(single_set (x2reg)));
++ rtx_insn * newinsn = make_insn_raw (pattern);
++
++ if (!insn_invalid_p (newinsn, 0))
+ {
-
-- rtx link;
-+ rtx link;
-
-- fprintf (
-- stderr,
-- "condition met, removing compare and joining insns - omit reg %d\n",
-- REGNO(dst));
-+ fprintf (
-+ stderr,
-+ "condition met, removing compare and joining insns - omit reg %d\n",
-+ REGNO(dst));
-
-- for (link = REG_NOTES(x2reg); link;
-- link = XEXP(link, 1))
-- if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
-- {
-- if (GET_CODE (link) == EXPR_LIST)
-- add_reg_note (
-- reg2x, REG_NOTE_KIND(link),
-- copy_insn_1 (XEXP(link, 0)));
-- else
-- add_shallow_copy_of_reg_note (reg2x,
-- link);
-- }
-+ for (link = REG_NOTES(x2reg); link;
-+ link = XEXP(link, 1))
-+ if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
-+ {
-+ if (GET_CODE (link) == EXPR_LIST)
-+ add_reg_note (reg2x, REG_NOTE_KIND(link),
-+ copy_insn_1 (XEXP(link, 0)));
-+ else
-+ add_shallow_copy_of_reg_note (reg2x, link);
-+ }
-
-- SET_INSN_DELETED(x2reg);
-- SET_INSN_DELETED(insn);
++ log ("(s) opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
++ reg_names[REGNO(dst)]);
++
+ SET_INSN_DELETED(x2reg);
++ SET_INSN_DELETED(reg2x);
+ SET_INSN_DELETED(insn);
-
-- df_insn_rescan (reg2x);
-+ df_insn_rescan (reg2x);
-
-- }
++
++ insn = emit_insn_after (pattern, reg2x);
++ insn_invalid_p (insn, 0);
++
+ ++change_count;
- }
- }
-- x2reg = 0;
-- continue;
- }
-- reg2x = 0;
++ }
++ }
++ }
+ x2reg = 0;
+ continue;
- }
++ }
+ reg2x = 0;
+ }
-
-- /* check for reg2x first, maybe fallback to x2reg. */
-- if (x2reg && reg2x == 0)
++
+ /* check for reg2x first, maybe fallback to x2reg. */
+ if (x2reg && reg2x == 0)
+ {
+ if (REG_P(SET_SRC(set)) && REGNO(SET_SRC(set)) == regno)
- {
-- if (REG_P(SET_SRC(set)) && REGNO(SET_SRC(set)) == regno)
-- {
-- reg2x = insn;
-- continue;
-- }
-- x2reg = 0;
++ {
+ reg2x = insn;
+ continue;
- }
++ }
+ x2reg = 0;
+ }
-
-- /* check for a match for x2reg. */
-- if (x2reg == 0)
++
+ /* check for a match for x2reg. */
+ if (x2reg == 0)
+ {
+ if (REG_P(SET_DEST(set)))
- {
-- if (REG_P(SET_DEST(set)))
-- {
-- x2reg = insn;
-- reg2x = 0;
-- regno = REGNO(SET_DEST(set));
-- }
++ {
+ x2reg = insn;
+ reg2x = 0;
+ regno = REGNO(SET_DEST(set));
- }
- }
- }
-+#endif
-+ return change_count;
-+}
-+
-+/*
-+ * Convert loops using a counting reg as offset with an address reg
-+ * into a loop with auto inc address regs.
-+ */
-+static int
-+offset_2_autoinc (void)
-+{
-+ rtx_insn *insn, *next;
-+ rtx_insn * reg_const = 0;
-+ int change_count = 0;
-+
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (!next || !LABEL_P(next) || LABEL_NUSES(next) != 1)
-+ continue;
-+
-+ if (!NONJUMP_INSN_P(insn))
-+ continue;
-+
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ rtx reg = SET_DEST(set);
-+ if (!REG_P(reg))
-+ continue;
-+
-+ rtx val = SET_SRC(set);
-+
-+
-+// fprintf(stderr, "possible start for offset_2_autoinc\n");
-+// debug_rtx(insn);
-+// debug_rtx(next);
-+
-+ }
-+
-+ return change_count;
- }
-
- /* Main entry point to the pass. */
-@@ -349,9 +388,11 @@ execute_bbb_optimizations (void)
-
- propagate_moves ();
-
-+ offset_2_autoinc ();
-+
- opt_strcpy ();
-
-- dump_insns ("bbb 1");
-+// dump_insns ("bbb 1");
-
- return 0;
- }
-diff --git a/gcc/except.c b/gcc/except.c
-index 156d7b76d249..194478f8454c 100644
---- gcc/except.c
-+++ gcc/except.c
-@@ -142,6 +142,7 @@ along with GCC; see the file COPYING3. If not see
- #include "cfgloop.h"
- #include "builtins.h"
- #include "tree-hash-traits.h"
-+#include "target-def.h"
-
- static GTY(()) int call_site_base;
-
-
-From 73b869461936fd68a37b9edc8f0e4eba48d5c440 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Apr 2017 16:03:47 +0200
-Subject: [PATCH 051/303] @R use a5 instead of fp
-
----
- gcc/config/m68k/amigaos.h | 6 +-----
- 1 file changed, 1 insertion(+), 5 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 7259611edc9e..ce47723e962f 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -153,11 +153,7 @@ amiga_named_section (const char *name, unsigned int flags, tree decl);
- #define FRAME_POINTER_REGNUM 13
-
- #undef M68K_REGNAME
--#define M68K_REGNAME(r) ( \
-- ( ((r) == FRAME_POINTER_REGNUM) \
-- && frame_pointer_needed) ? \
-- M68K_FP_REG_NAME : reg_names[(r)])
--
-+#define M68K_REGNAME(r) (reg_names[(r)])
-
- /* The AmigaOS ABI does not define how structures should be returned, so,
- contrary to 'm68k.h', we prefer a multithread-safe solution. */
-
-From 626d238b27f86a4369aeb13ad11153accd414f90 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Apr 2017 16:06:55 +0200
-Subject: [PATCH 052/303] @R make MEM_P more expensive than REG_P
-
----
- gcc/config/m68k/m68k.c | 30 ++++++++++++++++++++++++++++++
- 1 file changed, 30 insertions(+)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index d60371a92bc6..6c0d9211598d 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -2928,6 +2928,17 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);
- return true;
- }
-+ /* reg + value */
-+// if (mode == SImode
-+// && REG_P(XEXP(x, 0))) {
-+// if (m68k_rtx_costs(XEXP(x, 1), mode, PLUS, 1, total, speed))
-+// {
-+// if (REGNO_REG_CLASS(REGNO(XEXP(x, 0))) == ADDR_REGS)
-+// *total += 4;
-+// return true;
-+// }
-+// }
-+
- return false;
-
- case ASHIFT:
-@@ -2996,6 +3007,25 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- *total = 0;
- return false;
-
-+ case MEM:
-+ {
-+ /* simple but not exact */
-+ rtx y = XEXP(x, 0);
-+ int yc = GET_CODE(y);
-+ if (yc == REG || yc == PRE_INC || yc == POST_INC || yc == POST_DEC)
-+ *total += 4;
-+ else
-+ if (yc == PRE_DEC)
-+ *total += 6;
-+ else
-+ *total += 8;
-+
-+ if (mode != QImode && mode != QImode)
-+ *total += 4;
-+
-+ return true;
-+ }
-+
- default:
- return false;
- }
-
-From 9c9c8b4c31a9ed000a27ff22245ad21b7ad21e67 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Apr 2017 16:08:30 +0200
-Subject: [PATCH 053/303] @R added reg life analysis to own optimizer
-
----
- gcc/bbb-opts.c | 793 ++++++++++++++++++++++++++++++++++++++++++++++++---------
- gcc/passes.def | 1 +
- 2 files changed, 672 insertions(+), 122 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index aeec7a8b4e6a..7fd01139d0f3 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -25,11 +25,16 @@
- * #1 propagate_moves
- * check if a->b->a can be moved out of a loop.
- *
-- * #2 strcpy
-+ * #2 strcpy_opt
- * move a,reg
- * move reg,b
- * cmp #0,reg
-- * jne/jeq
-+ * jcc
-+ *
-+ * ->
-+ * move a,b
-+ * jcc
-+ *
- */
-
- #include "config.h"
-@@ -49,8 +54,285 @@
- #include <vector>
- #include <map>
-
--extern void
--dump_insns (char const * name);
-+/* enough for m68k. */
-+typedef unsigned insn_info; //[(FIRST_PSEUDO_REGISTER + sizeof(unsigned) * 8 - 1) / (sizeof(unsigned) * 8)];
-+
-+static inline void
-+resetii (unsigned & ii)
-+{
-+ ii = 0;
-+}
-+
-+static inline void
-+setii (unsigned regno, unsigned & ii)
-+{
-+ ii |= 1 << regno;
-+}
-+
-+static inline void
-+clearii (unsigned regno, unsigned & ii)
-+{
-+ ii &= ~(1 << regno);
-+}
-+
-+static inline bool
-+getii (unsigned regno, unsigned & ii)
-+{
-+ return ii & (1 << regno) ? true : false;
-+}
-+
-+/* scan rtx for registers. */
-+static void
-+scanii (rtx x, unsigned & ii)
-+{
-+ if (REG_P(x))
-+ {
-+ setii (REGNO(x), ii);
-+ return;
-+ }
-+
-+ RTX_CODE code = GET_CODE(x);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ scanii (XEXP(x, i), ii);
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ scanii (XVECEXP(x, i, j), ii);
-+ }
-+}
-+
-+static std::vector<rtx_insn *> insns;
-+static std::vector<rtx_insn *> jumps;
-+static std::map<rtx_insn *, unsigned> insn2index;
-+static std::vector<insn_info> infos;
-+
-+static void
-+clear (void)
-+{
-+ insns.clear ();
-+ jumps.clear ();
-+ insn2index.clear ();
-+ infos.clear ();
-+}
-+
-+static void
-+dump_costs (void)
-+{
-+ rtx d0 = gen_raw_REG (SImode, 0);
-+ rtx d0b = gen_raw_REG (QImode, 0);
-+ rtx d1 = gen_raw_REG (SImode, 1);
-+ rtx d1b = gen_raw_REG (QImode, 1);
-+ rtx a0 = gen_raw_REG (SImode, 8);
-+ rtx a1 = gen_raw_REG (SImode, 9);
-+
-+ struct ICO
-+ {
-+ char const * name;
-+ rtx set;
-+ } data[] =
-+ {
-+ { "move d0,(a0)", gen_rtx_SET(gen_rtx_MEM (SImode, a0), d0) },
-+ { "move a0,d0", gen_rtx_SET(d0, a0) },
-+ { "move (a0),d0", gen_rtx_SET(d0, gen_rtx_MEM (SImode, a0)) },
-+ { "move d0,(a0)", gen_rtx_SET(gen_rtx_MEM (SImode, a0), d0) },
-+ { "move d1,(a1)+", gen_rtx_SET(d1, gen_rtx_MEM (SImode, gen_rtx_POST_INC (SImode, a1))) },
-+ { "move (a0),(a1)", gen_rtx_SET(gen_rtx_MEM (SImode, a1), gen_rtx_MEM (SImode, a0)) },
-+ { 0, 0 } }, *p;
-+
-+ for (p = data; p->name; ++p)
-+ {
-+ int cost = insn_rtx_cost (p->set, true);
-+ fprintf (stderr, "%s: %d\n", p->name, cost);
-+ }
-+}
-+
-+
-+static void
-+dump_insns (char const * name)
-+{
-+ rtx_insn *insn, *next;
-+ fprintf(stderr, "====================================: %s\n", name);
-+ for (unsigned i = 0; i < insns.size(); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+
-+ for (int j = 0; j < 8; ++j)
-+ if (getii(j, ii))
-+ fprintf(stderr, "d%d ", j);
-+
-+ for (int j = 8; j < 16; ++j)
-+ if (getii(j, ii))
-+ fprintf(stderr, "a%d ", j-8);
-+
-+ fprintf(stderr, "\t");
-+ debug_rtx(insns[i]);
-+ }
-+}
-+
-+
-+/*
-+ * Create a filtered view of insns - keep only those to work with.
-+ */
-+static void
-+filter_insns ()
-+{
-+ rtx_insn *insn, *next;
-+ clear ();
-+
-+ df_insn_rescan_all ();
-+
-+ /* create a vector with relevant insn. */
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
-+ {
-+ // debug_rtx (insn);
-+ if (JUMP_P(insn))
-+ jumps.push_back(insn);
-+
-+ insn2index.insert (std::make_pair (insn, insns.size ()));
-+ insns.push_back (insn);
-+ }
-+ }
-+
-+ /* prepare insn_info */
-+ insn_info ii;
-+ resetii (ii);
-+ for (unsigned i = 0; i < insns.size (); ++i)
-+ {
-+ infos.push_back (ii);
-+ }
-+
-+ /* own analyze life */
-+ std::vector<std::pair<unsigned, insn_info>> todo;
-+ todo.push_back (std::make_pair (insns.size () - 1, ii));
-+
-+ int pass = 0;
-+ while (!todo.empty ())
-+ {
-+ std::pair<unsigned, insn_info> p = *todo.rbegin ();
-+ todo.pop_back ();
-+
-+ insn_info ii = p.second;
-+
-+ for (int pos = p.first; pos >= 0; --pos)
-+ {
-+ rtx_insn * insn = insns[pos];
-+
-+ if (pass && ii == infos[pos])
-+ break;
-+
-+ ii |= infos[pos];
-+
-+ if (LABEL_P(insn))
-+ {
-+ /* work on all jumps referring to that label. */
-+ for (std::vector<rtx_insn *>::iterator i = jumps.begin (); i != jumps.end (); ++i)
-+ {
-+ if (JUMP_LABEL(*i) == insn)
-+ {
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find (*i);
-+ if (j != insn2index.end())
-+ todo.push_back (std::make_pair (j->second, ii));
-+ }
-+ }
-+ continue;
-+ }
-+
-+ rtx set = single_set (insn);
-+ if (set == 0)
-+ {
-+ if (JUMP_P(insn)) {
-+ resetii(ii);
-+ setii(0, ii);
-+ infos[pos] = ii;
-+ continue;
-+ }
-+ fprintf(stderr, "##### ");
-+ debug_rtx(insn);
-+ continue;
-+ }
-+
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+
-+ debug_rtx(insn);
-+
-+ if (CALL_P(insn))
-+ {
-+ /* a call sets d0 and kills d1,a0,a1. */
-+ if (getii (1, ii))
-+ fprintf (stderr, "d1 used after call\n");
-+ if (getii (8, ii))
-+ fprintf (stderr, "a0 used after call\n");
-+ if (getii (9, ii))
-+ fprintf (stderr, "a1 used after call\n");
-+
-+ resetii (ii);
-+ // use regs depending on flag mregparm
-+ for (int i = 0; i < amigaos_regparm; ++i)
-+ {
-+ setii (i, ii);
-+ setii (i + 8, ii);
-+ }
-+
-+ // check for reg use
-+ if (REG_P(src))
-+ setii (REGNO(src), ii);
-+
-+ infos[pos] = ii;
-+ continue;
-+ }
-+
-+ if (JUMP_P(insn))
-+ {
-+ if (ANY_RETURN_P(src))
-+ {
-+ resetii (ii);
-+ setii (0, ii);
-+ }
-+ else
-+ {
-+ ii |= infos[pos];
-+
-+ // check for reg use
-+ if (REG_P(src))
-+ setii (REGNO(src), ii);
-+
-+ }
-+ infos[pos] = ii;
-+ continue;
+ }
-+
-+ // scan insn for regs
-+ // a def stop propagation
-+ // a use starts propagation
-+ // also add use to current ii
-+ insn_info use;
-+ resetii (use);
-+
-+ insn_info def;
-+ resetii (def);
-+
-+ scanii (src, use);
-+ if (REG_P(dst))
-+ setii (REGNO(dst), def);
-+ else
-+ scanii (dst, use);
-+
-+ infos[pos] = use | ii;
-+
-+ ii &= ~def;
-+ ii |= use;
+ }
-+ ++pass;
+ }
-+
++#endif
++ return change_count;
+}
-
- /*
- * #1 propagate a->b->a moves out of a loop.
-@@ -102,29 +384,34 @@ dump_insns (char const * name);
- move.b d1,(a0)+
- cmp.b #0, d1
- jne .L6
-+
- *
-+ * Also allow exit jumps, if the modification of the reg is const
-+ * and insert a correction after the exit label.
-+ * The label must only be reachable by the exit jump.
- */
--static int
-+static unsigned
- propagate_moves ()
- {
-- int change_count = 0;
-- rtx_insn *insn, *next;
-+ unsigned change_count = 0;
- rtx_insn * current_label = 0;
-- std::vector<rtx_insn *> reg_reg;
-+ unsigned current_label_index;
-+ std::vector<unsigned> reg_reg;
-+ std::vector<rtx_insn *> jump_out;
-
-- for (insn = get_insns (); insn; insn = next)
-+ /* start at 1 since there must be an insn before the label. */
-+ for (unsigned index = 1; index < insns.size (); ++index)
- {
-- next = NEXT_INSN (insn);
--
-- if (DEBUG_INSN_P(insn))
-- continue;
-+ rtx_insn * insn = insns[index];
-
- if (LABEL_P(insn))
- {
- if (LABEL_NUSES(insn) == 1)
- {
- current_label = insn;
-+ current_label_index = index;
- reg_reg.clear ();
-+ jump_out.clear ();
- }
- else
- current_label = 0;
-@@ -142,59 +429,180 @@ propagate_moves ()
- rtx src = SET_SRC(set);
- rtx dst = SET_DEST(set);
- if (REG_P(src) && REG_P(dst))
-- reg_reg.push_back (insn);
-+ reg_reg.push_back (index);
- }
-+ else
-+ current_label = 0;
-+
- continue;
- }
-
- if (JUMP_P(insn))
- {
-- if (JUMP_LABEL (insn) == current_label && reg_reg.size () > 1)
-+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ if (label != current_label)
-+ {
-+ /* collect the labels for a later check if a fixup is possible. */
-+ if (LABEL_NUSES(label) == 1 && BARRIER_P(PREV_INSN (label)))
-+ jump_out.push_back (label);
-+ else
-+ current_label = 0;
-+ continue;
-+ }
-+
-+ if (reg_reg.size () > 1)
- {
- /* Search for reg/reg pairs. */
-- for (std::vector<rtx_insn *>::iterator i = reg_reg.begin ();
-- i != reg_reg.end () && i + 1 != reg_reg.end ();)
-+ for (std::vector<unsigned>::iterator i = reg_reg.begin (); i != reg_reg.end () && i + 1 != reg_reg.end ();
-+ )
- {
- bool inc = true;
-- for (std::vector<rtx_insn *>::iterator j = i + 1; j != reg_reg.end ();)
-+ for (std::vector<unsigned>::iterator j = i + 1; j != reg_reg.end ();)
- {
-- rtx seti = single_set (*i);
-+ rtx_insn * ii = insns[*i];
-+ rtx seti = single_set (ii);
- rtx srci = SET_SRC(seti);
- rtx dsti = SET_DEST(seti);
-- rtx setj = single_set (*j);
-+ rtx_insn * jj = insns[*j];
-+ rtx setj = single_set (jj);
- rtx srcj = SET_SRC(setj);
- rtx dstj = SET_DEST(setj);
-
- if (rtx_equal_p (srci, dstj) && rtx_equal_p (srcj, dsti))
- {
- /* Ensure correct usage. */
-- if (!reg_used_between_p (srci, current_label, *i)
-- && !reg_used_between_p (srci, *i, *j)
-- && !reg_used_between_p (srci, *j, insn)
-- && !reg_used_between_p (dsti, current_label, *i)
-- && !reg_used_between_p (dsti, *j, insn))
-+ if (!reg_used_between_p (srci, current_label, ii) && !reg_used_between_p (srci, ii, jj)
-+ && !reg_used_between_p (srci, jj, insn) && !reg_used_between_p (dsti, current_label, ii)
-+ && !reg_used_between_p (dsti, jj, insn))
- {
-- fprintf (stderr,
-- "condition met, moving regs %d, %d\n",
-- REGNO(srci), REGNO(dsti));
--
-- /* Move out of loop. */
-- remove_insn (*i);
-- if (PREV_INSN (current_label))
-- add_insn_after (*i, PREV_INSN (current_label),
-- 0);
-- else
-- add_insn_before (*i, current_label, 0);
--
-- remove_insn (*j);
-- add_insn_after (*j, insn, 0);
--
-- reg_reg.erase (j);
-- reg_reg.erase (i);
-- j = reg_reg.end ();
-- inc = false;
--
-- ++change_count;
-+ std::vector<int> fixups;
-+
-+ /* if there are jumps out of the loop,
-+ * check if the modification occurs before the jump,
-+ * and if, that it's a plus const.
-+ */
-+ if (jump_out.size ())
-+ {
-+ std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
-+ int fixup = 0;
-+ fprintf (stderr, "need %d jump out fixups\n", jump_out.size ());
-+
-+ for (unsigned k = *i + 1; k != *j; ++k)
-+ {
-+ rtx_insn * check = insns[k];
-+ if (JUMP_P(check))
-+ {
-+ fixups.push_back (fixup);
-+ if (++label_iter == jump_out.end ())
-+ break;
-+ continue;
-+ }
-+
-+ if (reg_overlap_mentioned_p (dsti, PATTERN (check)))
-+ {
-+ /* right now only support auto_incs. */
-+ rtx set = single_set (check);
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+
-+ if (reg_overlap_mentioned_p (dsti, dst))
-+ {
-+ if (REG_P(dst))
-+ break;
-+ if (!MEM_P(dst))
-+ break;
-+
-+ rtx x = XEXP(dst, 0);
-+ if (GET_CODE(x) == REG)
-+ fixup += 0; // direct use
-+ else if (GET_CODE(x) == PRE_INC ||
-+ GET_CODE(x) == POST_INC)
-+ fixup -= GET_MODE_SIZE(GET_MODE(dst));
-+ else if (GET_CODE(dst) == PRE_DEC ||
-+ GET_CODE(dst) == POST_DEC)
-+ fixup += GET_MODE_SIZE(GET_MODE(dst));
-+ else
-+ break;
-+ }
-+
-+ if (reg_overlap_mentioned_p (dsti, src))
-+ {
-+ if (REG_P(src))
-+ fixup += 0;
-+ else
-+ {
-+ if (!MEM_P(src))
-+ break;
-+
-+ rtx x = XEXP(src, 0);
-+ if (GET_CODE(x) == REG)
-+ fixup += 0; // direct use
-+ else if (GET_CODE(x) == PRE_INC ||
-+ GET_CODE(x) == POST_INC)
-+ fixup -= GET_MODE_SIZE(GET_MODE(dst));
-+ else if (GET_CODE(dst) == PRE_DEC ||
-+ GET_CODE(dst) == POST_DEC)
-+ fixup += GET_MODE_SIZE(GET_MODE(dst));
-+ else
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ /* got a fixup for all jump_outs? */
-+ if (fixups.size () == jump_out.size ())
-+ {
-+ rtx_insn * before = insns[current_label_index - 1];
-+ rtx_insn * after = insns[index + 1];
-+ rtx bset = single_set (before);
-+
-+ fprintf (stderr, "condition met, moving regs %d, %d\n", REGNO(srci), REGNO(dsti));
-+
-+ /* Move in front of loop and mark as dead. */
-+ remove_insn (ii);
-+ add_insn_after (ii, before, 0);
-+ add_reg_note (ii, REG_DEAD, srci);
-+
-+ /* Plus check if the reg was just loaded. */
-+ if (bset)
-+ {
-+ rtx bdst = SET_DEST(bset);
-+ if (REG_P(bdst) && REGNO(bdst) == REGNO(srci))
-+ {
-+ SET_DEST(bset) = dsti;
-+ SET_INSN_DELETED(ii);
-+ }
-+ }
-+
-+ /* Move behind loop - into next BB. */
-+ remove_insn (jj);
-+ add_insn_before (jj, after, 0);
+
-+ reg_reg.erase (j);
-+ reg_reg.erase (i);
-+ j = reg_reg.end ();
-+ inc = false;
-+
-+ df_insn_rescan (ii);
-+ df_insn_rescan (jj);
-+
-+ /* add fixes if there were jumps out of the loop. */
-+ if (jump_out.size ())
-+ {
-+ fprintf (stderr, "fixing %d jump outs\n", jump_out.size ());
-+
-+ for (unsigned k = 0; k < jump_out.size (); ++k)
-+ {
-+ rtx neu = gen_rtx_SET(
-+ dstj, gen_rtx_PLUS(Pmode, dsti, gen_rtx_CONST_INT(Pmode, fixups[k])));
-+ rtx_insn * neui = emit_insn_after (neu, jump_out[k]);
-+ df_insn_rescan (neui);
-+ }
-+ }
-+ ++change_count;
-+ }
- }
- }
- if (inc)
-@@ -222,19 +630,18 @@ propagate_moves ()
- *
- * Use a simple state machine to find the patterns.
- */
--static int
-+static unsigned
- opt_strcpy ()
- {
-- int change_count = 0;
-+ unsigned change_count = 0;
- #if HAVE_cc0
-- rtx_insn *insn, *next;
- rtx_insn * x2reg = 0;
- rtx_insn * reg2x;
- unsigned int regno;
-
-- for (insn = get_insns (); insn; insn = next)
-+ for (unsigned index = 0; index < insns.size (); ++index)
- {
-- next = NEXT_INSN (insn);
-+ rtx_insn * insn = insns[index];
-
- if (!NONJUMP_INSN_P(insn))
- continue;
-@@ -251,26 +658,22 @@ opt_strcpy ()
- rtx dst = XEXP(src, 0);
- src = XEXP(src, 1);
-
-- if (CONST_INT_P(src) && INTVAL(src) == 0
-- && find_reg_note (insn, REG_DEAD, dst))
-+ if (CONST_INT_P(src) && INTVAL(src) == 0 && find_reg_note (insn, REG_DEAD, dst))
- {
- /* now check via NOTICE_UPDATE_CC*/
-- NOTICE_UPDATE_CC (PATTERN (reg2x), reg2x);
-- if (cc_status.flags == 0
-- && rtx_equal_p (dst, cc_status.value2))
-+ NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
-+ if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2))
- {
- int num_clobbers_to_add = 0;
- int insn_code_number;
-
- SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
-- insn_code_number = recog (PATTERN (reg2x), reg2x,
-- &num_clobbers_to_add);
-+ insn_code_number = recog (PATTERN (reg2x), reg2x, &num_clobbers_to_add);
-
- if (insn_code_number < 0)
- {
- /* restore register. */
-- SET_SRC(single_set(reg2x)) = SET_DEST(
-- single_set (x2reg));
-+ SET_SRC(single_set(reg2x)) = SET_DEST(single_set (x2reg));
- }
- else
- {
-@@ -278,17 +681,14 @@ opt_strcpy ()
- rtx link;
-
- fprintf (
-- stderr,
-- "condition met, removing compare and joining insns - omit reg %d\n",
-- REGNO(dst));
-+ stderr,
-+ "condition met, removing compare and joining insns - omit reg %d\n", REGNO(dst));
-
-- for (link = REG_NOTES(x2reg); link;
-- link = XEXP(link, 1))
-+ for (link = REG_NOTES(x2reg); link; link = XEXP(link, 1))
- if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
- {
- if (GET_CODE (link) == EXPR_LIST)
-- add_reg_note (reg2x, REG_NOTE_KIND(link),
-- copy_insn_1 (XEXP(link, 0)));
-+ add_reg_note (reg2x, REG_NOTE_KIND(link), copy_insn_1 (XEXP(link, 0)));
- else
- add_shallow_copy_of_reg_note (reg2x, link);
- }
-@@ -338,45 +738,165 @@ opt_strcpy ()
- * Convert loops using a counting reg as offset with an address reg
- * into a loop with auto inc address regs.
- */
--static int
-+static unsigned
- offset_2_autoinc (void)
- {
-- rtx_insn *insn, *next;
-+ unsigned change_count = 0;
-+#if 0
- rtx_insn * reg_const = 0;
-- int change_count = 0;
-
-- for (insn = get_insns (); insn; insn = next)
-+ for (unsigned index = 0; index < insns.size (); ++index)
- {
-- next = NEXT_INSN (insn);
-+ rtx_insn * insn = insns[index];
-
- if (!next || !LABEL_P(next) || LABEL_NUSES(next) != 1)
-- continue;
-+ continue;
-
- if (!NONJUMP_INSN_P(insn))
-- continue;
-+ continue;
-
- rtx set = single_set (insn);
- if (!set)
-- continue;
-+ continue;
-
- rtx reg = SET_DEST(set);
- if (!REG_P(reg))
-- continue;
-+ continue;
-
- rtx val = SET_SRC(set);
-
--
- // fprintf(stderr, "possible start for offset_2_autoinc\n");
--// debug_rtx(insn);
--// debug_rtx(next);
-+// //debug_rtx(insn);
-+// //debug_rtx(next);
-
- }
-
-+#endif
- return change_count;
- }
-
--/* Main entry point to the pass. */
+/*
+ * convert
+ *
@@ -8398,1053 +3730,54 @@ index aeec7a8b4e6a..7fd01139d0f3 100755
+ (nil)))
+ */
+static unsigned
-+commute_add_move (void)
++opt_commute_add_move (void)
+{
+ unsigned change_count = 0;
+
-+ for (unsigned index = 0; index + 1 < insns.size (); ++index)
++ for (unsigned index = 0; index + 1 < infos.size (); ++index)
+ {
-+ rtx_insn * insn = insns[index];
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ rtx reg1 = SET_DEST(set);
-+ if (!REG_P(reg1))
++ insn_info & ii = infos[index];
++ if (ii.get_dst_regno () < 8 || ii.get_dst_regno () > 15 || ii.get_src_op () != PLUS
++ || ii.get_src_regno () == ii.get_dst_regno () || !ii.get_src_intval ())
+ continue;
+
-+ rtx plus = SET_SRC(set);
-+ if (GET_CODE(plus) != PLUS)
-+ continue;
++ insn_info & jj = infos[index + 1];
+
-+ rtx reg2 = XEXP(plus, 0);
-+ if (!REG_P(reg2))
++ if (!jj.get_dst_mem_reg () || jj.get_dst_mem_regno () != ii.get_src_regno ()
++ || jj.get_src_regno () == ii.get_dst_regno () || GET_MODE_SIZE(jj.get_mode()) != ii.get_src_intval ())
+ continue;
+
-+ rtx cnst = XEXP(plus, 1);
-+ if (!CONST_INT_P(cnst))
-+ continue;
++ rtx_insn * insn = ii.get_insn ();
+
-+ rtx_insn * next = insns[index + 1];
++ rtx_insn * next = jj.get_insn ();
+ rtx set2 = single_set (next);
-+ if (!set2)
-+ continue;
-+
+ rtx dst = SET_DEST(set2);
-+ if (!MEM_P(dst) || GET_MODE_SIZE(GET_MODE(dst)) != INTVAL(cnst))
-+ continue;
-+
-+ rtx memreg = XEXP(dst, 0);
-+ if (!REG_P(memreg) || REGNO(memreg) != REGNO(reg2))
++ if (!MEM_P(dst))
+ continue;
-
-+ int oldcost1 = insn_rtx_cost (set, true);
-+ int oldcost2 = insn_rtx_cost (set2, true);
-+
-+ fprintf (stderr, "commute_add_move found, oldcost: %d = %d + %d\n", oldcost1 + oldcost2, oldcost1, oldcost2);
-+
-+ //debug_rtx (insn);
-+ //debug_rtx (next);
+
-+ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1);
++ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), ii.get_dst_reg ());
+ rtx newmem = replace_equiv_address_nv (dst, pinc);
+
-+ if (validate_change (next, &SET_DEST(set2), newmem, 0))
-+ {
-+ SET_INSN_DELETED(insn);
-+
-+ insn = emit_insn_before (gen_movsi (reg1, reg2), next);
-+
-+ add_reg_note (next, REG_INC, reg1);
-+
-+ int newcost1 = insn_rtx_cost (set, true);
-+ int newcost2 = insn_rtx_cost (set2, true);
-+
-+ fprintf (stderr, "commute_add_move found, newcost: %d = %d + %d\n", newcost1 + newcost2, newcost1, newcost2);
-+
-+ //debug_rtx (insn);
-+ //debug_rtx (next);
-+
-+ df_insn_rescan (insn);
-+ df_insn_rescan (next);
-+
-+ ++change_count;
-+ }
-+ }
-+ return change_count;
-+}
-+
-+static unsigned
-+const_cmp_to_sub (void)
-+{
-+ unsigned change_count = 0;
-+#if HAVE_cc0
-+ for (unsigned index = 0; index + 1 < insns.size (); ++index)
-+ {
-+ rtx_insn * insn = insns[index];
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ rtx dst = SET_DEST(set);
-+ if (dst != cc0_rtx)
-+ continue;
-+
-+ fprintf (stderr, "cc0:");
-+ debug_rtx (insn);
-+ }
-+#endif
-+ return change_count;
-+}
-+
-+/* Main entry point to the pass. */
- static unsigned int
- execute_bbb_optimizations (void)
- {
-@@ -385,58 +905,87 @@ execute_bbb_optimizations (void)
- df_analyze ();
-
- // dump_insns ("bbb 0");
-+ filter_insns ();
-+
-+ for (;;)
-+ {
-+ int done = 1;
-+ if (propagate_moves ())
-+ done = 0, filter_insns ();
-+
-+ if (offset_2_autoinc ())
-+ done = 0, filter_insns ();
-
-- propagate_moves ();
-+ if (opt_strcpy ())
-+ done = 0, filter_insns ();
-
-- offset_2_autoinc ();
-+ if (commute_add_move ())
-+ done = 0, filter_insns ();
-
-- opt_strcpy ();
-+ if (const_cmp_to_sub ())
-+ done = 0, filter_insns ();
-
--// dump_insns ("bbb 1");
-+ if (done)
-+ break;
-+ }
-+
-+ dump_insns ("bbb 1");
-+ clear ();
-+
-+ dump_costs ();
-
- return 0;
- }
-
- namespace
-+{
-+
-+ const pass_data pass_data_bbb_optimizations =
-+ { RTL_PASS, /* type */
-+ "bbb", /* name */
-+ OPTGROUP_NONE, /* optinfo_flags */
-+ TV_NONE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ ( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ };
-+
-+ class pass_bbb_optimizations : public rtl_opt_pass
- {
-+ public:
-+ pass_bbb_optimizations (gcc::context *ctxt) :
-+ rtl_opt_pass (pass_data_bbb_optimizations, ctxt)
-+ {
-+ }
-
-- const pass_data pass_data_bbb_optimizations =
-- {
-- RTL_PASS, /* type */
-- "bbb", /* name */
-- OPTGROUP_NONE, /* optinfo_flags */
-- TV_NONE, /* tv_id */
-- 0, /* properties_required */
-- 0, /* properties_provided */
-- 0, /* properties_destroyed */
-- 0, /* todo_flags_start */
-- ( TODO_df_finish | TODO_df_verify ), /* todo_flags_finish */
-- };
--
-- class pass_bbb_optimizations : public rtl_opt_pass
-- {
-- public:
-- pass_bbb_optimizations (gcc::context *ctxt)
-- : rtl_opt_pass (pass_data_bbb_optimizations, ctxt)
-- {}
--
-- /* opt_pass methods: */
-- virtual bool gate (function *)
-- {
-- return true;
-- }
--
-- virtual unsigned int execute (function *)
-- {
-- return execute_bbb_optimizations ();
-- }
--
-- }; // class pass_bbb_optimizations
--
-- } // anon namespace
-+ /* opt_pass methods: */
-+ virtual bool
-+ gate (function *)
-+ {
-+ return TARGET_AMIGA;
-+ }
-+
-+ virtual unsigned int
-+ execute (function *)
-+ {
-+ return execute_bbb_optimizations ();
-+ }
-+
-+ opt_pass *
-+ clone ()
-+ {
-+ return new pass_bbb_optimizations (m_ctxt);
-+ }
-+
-+ };
-+// class pass_bbb_optimizations
-+
-+}// anon namespace
-
- rtl_opt_pass *
--make_pass_bbb_optimizations (gcc::context *ctxt)
-- {
-- return new pass_bbb_optimizations (ctxt);
-- }
-+make_pass_bbb_optimizations (gcc::context * ctxt)
-+{
-+ return new pass_bbb_optimizations (ctxt);
-+}
-diff --git a/gcc/passes.def b/gcc/passes.def
-index 45ff86c383e4..ca5b94552d4e 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -460,6 +460,7 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_stack_adjustments);
- NEXT_PASS (pass_fast_rtl_dce);
- NEXT_PASS (pass_reorder_blocks);
-+ NEXT_PASS (pass_bbb_optimizations);
- NEXT_PASS (pass_branch_target_load_optimize2);
- NEXT_PASS (pass_leaf_regs);
- NEXT_PASS (pass_split_before_sched2);
-
-From a56cbf57c5732afe7dfe0b67472284434ccfcbb2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Apr 2017 22:54:53 +0200
-Subject: [PATCH 054/303] @B fix resident options, add -fbbb
-
----
- gcc/config/m68k/amigaos.h | 2 +-
- gcc/config/m68k/amigaos.opt | 10 +++++++---
- 2 files changed, 8 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index ce47723e962f..49dd90d745c3 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -454,7 +454,7 @@ extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
- #define SUBTARGET_OVERRIDE_OPTIONS \
- do \
- { \
-- if (!TARGET_68020 && flag_mybaserel==2) \
-+ if (!TARGET_68020 && flag_pic==4) \
- error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \
- if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
- error ("-mregparm=x with 1 <= x <= %d\n", AMIGAOS_MAX_REGPARM); \
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index f985cf5e2845..2d8bed0a9103 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -32,13 +32,17 @@ Target Report Var(flag_pic,4)
- data is adressed relativ to a4 with 32 bit offsets
-
- resident
--Target Common Report Var(flag_mybaserel,1)
-+Target Common Report Var(flag_pic,3)
- data is adressed relativ to a4, linked as resident
-
- resident32
--Target Common Report Var(flag_mybaserel,2)
-+Target Common Report Var(flag_pic,4)
- data is adressed relativ to a4 with 32 bit offsets, linked as resident
-
- mcrt=
- Target RejectNegative Var(amigaos_crt) Joined
--Specify startup binary
-\ No newline at end of file
-+Specify startup binary
-+
-+fbbb
-+Target Var(flag_bbb_opts,1) UInteger Init(0)
-+Enable Bebbo's optimizations
-
-From 01bd7d9ab157a9d973115a47cb9d24446f30f619 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Apr 2017 22:55:25 +0200
-Subject: [PATCH 055/303] @I cleanup
-
----
- gcc/config/m68k/m68k.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 6c0d9211598d..52eabeaafb23 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -2928,16 +2928,6 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);
- return true;
- }
-- /* reg + value */
--// if (mode == SImode
--// && REG_P(XEXP(x, 0))) {
--// if (m68k_rtx_costs(XEXP(x, 1), mode, PLUS, 1, total, speed))
--// {
--// if (REGNO_REG_CLASS(REGNO(XEXP(x, 0))) == ADDR_REGS)
--// *total += 4;
--// return true;
--// }
--// }
-
- return false;
-
-
-From ab8a4e993790f397307d8ec74581791e12470cf9 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Apr 2017 23:00:59 +0200
-Subject: [PATCH 056/303] @B fix life analysis and commute_add_move, also some
- cleanup
-
----
- gcc/bbb-opts.c | 314 +++++++++++++++++++++++++++++++++------------------------
- 1 file changed, 180 insertions(+), 134 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 7fd01139d0f3..48e2fa3fd255 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1,5 +1,6 @@
- /* Bebbo's Optimizations.
-- Copyright (C) 2010-2016 Free Software Foundation, Inc.
-+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
-+ Copyright (C) 2017 Stefan "Bebbo" Franke.
-
- This file is part of GCC.
-
-@@ -26,14 +27,7 @@
- * check if a->b->a can be moved out of a loop.
- *
- * #2 strcpy_opt
-- * move a,reg
-- * move reg,b
-- * cmp #0,reg
-- * jcc
-- *
-- * ->
-- * move a,b
-- * jcc
-+ * check if a temp reg can be eliminated.
- *
- */
-
-@@ -55,39 +49,91 @@
- #include <map>
-
- /* enough for m68k. */
--typedef unsigned insn_info; //[(FIRST_PSEUDO_REGISTER + sizeof(unsigned) * 8 - 1) / (sizeof(unsigned) * 8)];
--
--static inline void
--resetii (unsigned & ii)
-+struct insn_info
- {
-- ii = 0;
--}
-+ unsigned mask;
-
--static inline void
--setii (unsigned regno, unsigned & ii)
--{
-- ii |= 1 << regno;
--}
-+ insn_info () :
-+ mask (0)
-+ {
-+ }
-
--static inline void
--clearii (unsigned regno, unsigned & ii)
--{
-- ii &= ~(1 << regno);
--}
-+ inline void
-+ reset ()
-+ {
-+ mask = 0;
-+ }
-
--static inline bool
--getii (unsigned regno, unsigned & ii)
--{
-- return ii & (1 << regno) ? true : false;
--}
-+ inline void
-+ set (int regno)
-+ {
-+ mask |= 1 << regno;
-+ }
-+
-+ inline void
-+ unset (int regno)
-+ {
-+ mask &= ~(1 << regno);
-+ }
-+
-+ inline bool
-+ get (int regno)
-+ {
-+ return (mask & (1 << regno)) != 0;
-+ }
-+
-+ inline insn_info
-+ operator | (insn_info const & o) const
-+ {
-+ insn_info t;
-+ t.mask = mask | o.mask;
-+ return t;
-+ }
-+
-+ inline insn_info
-+ operator & (insn_info const & o) const
-+ {
-+ insn_info t;
-+ t.mask = mask & o.mask;
-+ return t;
-+ }
-+
-+ inline insn_info &
-+ operator |= (insn_info const & o)
-+ {
-+ mask |= o.mask;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ operator &= (insn_info const & o)
-+ {
-+ mask &= o.mask;
-+ return *this;
-+ }
-+
-+ inline bool
-+ operator == (insn_info const & o)
-+ {
-+ return mask == o.mask;
-+ }
-+
-+ inline insn_info
-+ operator ~ () const
-+ {
-+ insn_info t;
-+ t.mask = ~mask;
-+ return t;
-+ }
-+};
-
- /* scan rtx for registers. */
- static void
--scanii (rtx x, unsigned & ii)
-+scanii (rtx x, insn_info & ii)
- {
- if (REG_P(x))
- {
-- setii (REGNO(x), ii);
-+ ii.set (REGNO(x));
- return;
- }
-
-@@ -117,61 +163,27 @@ clear (void)
- infos.clear ();
- }
-
--static void
--dump_costs (void)
--{
-- rtx d0 = gen_raw_REG (SImode, 0);
-- rtx d0b = gen_raw_REG (QImode, 0);
-- rtx d1 = gen_raw_REG (SImode, 1);
-- rtx d1b = gen_raw_REG (QImode, 1);
-- rtx a0 = gen_raw_REG (SImode, 8);
-- rtx a1 = gen_raw_REG (SImode, 9);
--
-- struct ICO
-- {
-- char const * name;
-- rtx set;
-- } data[] =
-- {
-- { "move d0,(a0)", gen_rtx_SET(gen_rtx_MEM (SImode, a0), d0) },
-- { "move a0,d0", gen_rtx_SET(d0, a0) },
-- { "move (a0),d0", gen_rtx_SET(d0, gen_rtx_MEM (SImode, a0)) },
-- { "move d0,(a0)", gen_rtx_SET(gen_rtx_MEM (SImode, a0), d0) },
-- { "move d1,(a1)+", gen_rtx_SET(d1, gen_rtx_MEM (SImode, gen_rtx_POST_INC (SImode, a1))) },
-- { "move (a0),(a1)", gen_rtx_SET(gen_rtx_MEM (SImode, a1), gen_rtx_MEM (SImode, a0)) },
-- { 0, 0 } }, *p;
--
-- for (p = data; p->name; ++p)
-- {
-- int cost = insn_rtx_cost (p->set, true);
-- fprintf (stderr, "%s: %d\n", p->name, cost);
-- }
--}
--
--
- static void
- dump_insns (char const * name)
- {
-- rtx_insn *insn, *next;
-- fprintf(stderr, "====================================: %s\n", name);
-- for (unsigned i = 0; i < insns.size(); ++i)
-+ fprintf (stderr, "====================================: %s\n", name);
-+ for (unsigned i = 0; i < insns.size (); ++i)
- {
- insn_info & ii = infos[i];
-
- for (int j = 0; j < 8; ++j)
-- if (getii(j, ii))
-- fprintf(stderr, "d%d ", j);
-+ if (ii.get (j))
-+ fprintf (stderr, "d%d ", j);
-
- for (int j = 8; j < 16; ++j)
-- if (getii(j, ii))
-- fprintf(stderr, "a%d ", j-8);
-+ if (ii.get (j))
-+ fprintf (stderr, "a%d ", j - 8);
-
-- fprintf(stderr, "\t");
-- debug_rtx(insns[i]);
-+ fprintf (stderr, "\t");
-+ debug_rtx (insns[i]);
- }
- }
-
--
- /*
- * Create a filtered view of insns - keep only those to work with.
- */
-@@ -192,7 +204,7 @@ filter_insns ()
- {
- // debug_rtx (insn);
- if (JUMP_P(insn))
-- jumps.push_back(insn);
-+ jumps.push_back (insn);
-
- insn2index.insert (std::make_pair (insn, insns.size ()));
- insns.push_back (insn);
-@@ -201,13 +213,12 @@ filter_insns ()
-
- /* prepare insn_info */
- insn_info ii;
-- resetii (ii);
- for (unsigned i = 0; i < insns.size (); ++i)
- {
- infos.push_back (ii);
- }
-
-- /* own analyze life */
-+ /* own analyze reg life */
- std::vector<std::pair<unsigned, insn_info>> todo;
- todo.push_back (std::make_pair (insns.size () - 1, ii));
-
-@@ -236,53 +247,40 @@ filter_insns ()
- if (JUMP_LABEL(*i) == insn)
- {
- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find (*i);
-- if (j != insn2index.end())
-+ if (j != insn2index.end ())
- todo.push_back (std::make_pair (j->second, ii));
- }
- }
- continue;
- }
-
-- rtx set = single_set (insn);
-- if (set == 0)
-- {
-- if (JUMP_P(insn)) {
-- resetii(ii);
-- setii(0, ii);
-- infos[pos] = ii;
-- continue;
-- }
-- fprintf(stderr, "##### ");
-- debug_rtx(insn);
-- continue;
-- }
--
-- rtx src = SET_SRC(set);
-- rtx dst = SET_DEST(set);
--
-- debug_rtx(insn);
-+ rtx pattern = PATTERN (insn);
-
- if (CALL_P(insn))
- {
- /* a call sets d0 and kills d1,a0,a1. */
-- if (getii (1, ii))
-+ if (ii.get (1))
- fprintf (stderr, "d1 used after call\n");
-- if (getii (8, ii))
-+ if (ii.get (8))
- fprintf (stderr, "a0 used after call\n");
-- if (getii (9, ii))
-+ if (ii.get (9))
- fprintf (stderr, "a1 used after call\n");
-
-- resetii (ii);
-+ ii.unset(0);
-+ ii.unset(1);
-+ ii.unset(8);
-+ ii.unset(9);
-+
-+ // FIXME: get the DECL and read attributes.
- // use regs depending on flag mregparm
- for (int i = 0; i < amigaos_regparm; ++i)
- {
-- setii (i, ii);
-- setii (i + 8, ii);
-+ ii.set (i);
-+ ii.set (i + 8);
- }
-
- // check for reg use
-- if (REG_P(src))
-- setii (REGNO(src), ii);
-+ scanii (pattern, ii);
-
- infos[pos] = ii;
- continue;
-@@ -290,37 +288,55 @@ filter_insns ()
-
- if (JUMP_P(insn))
- {
-- if (ANY_RETURN_P(src))
-+ if (ANY_RETURN_P(pattern))
- {
-- resetii (ii);
-- setii (0, ii);
-+ ii.reset ();
-+ ii.set (0);
- }
- else
- {
- ii |= infos[pos];
-
- // check for reg use
-- if (REG_P(src))
-- setii (REGNO(src), ii);
-+ scanii(PATTERN(insn), ii);
-+
-+ }
-+ infos[pos] = ii;
-+ continue;
-+ }
++ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(ii.get_dst_reg (), ii.get_src_reg ()));
+
-
-+ rtx set = single_set (insn);
-+ if (set == 0)
-+ {
-+ if (GET_CODE (pattern) == USE)
-+ {
-+ rtx x = XEXP(pattern, 0);
-+ if (REG_P(x))
-+ ii.set(REGNO(x));
-+ infos[pos] = ii;
-+ continue;
- }
++ if (!insn_invalid_p (newinsn, 1) && validate_change (next, &SET_DEST(set2), newmem, 1) && apply_change_group ())
++ {
++ log ("(a) commute_add_move found\n");
+
-+ fprintf (stderr, "##### ");
-+ debug_rtx (insn);
-+ scanii (pattern, ii);
- infos[pos] = ii;
- continue;
- }
-
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
- // scan insn for regs
- // a def stop propagation
- // a use starts propagation
- // also add use to current ii
- insn_info use;
-- resetii (use);
--
- insn_info def;
-- resetii (def);
-
- scanii (src, use);
- if (REG_P(dst))
-- setii (REGNO(dst), def);
-+ def.set (REGNO(dst));
- else
- scanii (dst, use);
-
-@@ -808,16 +824,16 @@ commute_add_move (void)
- if (!set)
- continue;
-
-- rtx reg1 = SET_DEST(set);
-- if (!REG_P(reg1))
-+ rtx reg1dst = SET_DEST(set);
-+ if (!REG_P(reg1dst))
- continue;
-
- rtx plus = SET_SRC(set);
- if (GET_CODE(plus) != PLUS)
- continue;
-
-- rtx reg2 = XEXP(plus, 0);
-- if (!REG_P(reg2))
-+ rtx reg1src = XEXP(plus, 0);
-+ if (!REG_P(reg1src) || reg1src == reg1dst)
- continue;
-
- rtx cnst = XEXP(plus, 1);
-@@ -834,35 +850,35 @@ commute_add_move (void)
- continue;
-
- rtx memreg = XEXP(dst, 0);
-- if (!REG_P(memreg) || REGNO(memreg) != REGNO(reg2))
-+ if (!REG_P(memreg) || REGNO(memreg) != REGNO(reg1src))
- continue;
-
- int oldcost1 = insn_rtx_cost (set, true);
- int oldcost2 = insn_rtx_cost (set2, true);
-
-- fprintf (stderr, "commute_add_move found, oldcost: %d = %d + %d\n", oldcost1 + oldcost2, oldcost1, oldcost2);
-+ fprintf (stderr, "commute_add_move found, old cost: %d = %d + %d\n", oldcost1 + oldcost2, oldcost1, oldcost2);
-
-- //debug_rtx (insn);
-- //debug_rtx (next);
-+ debug_rtx (insn);
-+ debug_rtx (next);
-
-- rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1);
-+ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1dst);
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
- if (validate_change (next, &SET_DEST(set2), newmem, 0))
- {
- SET_INSN_DELETED(insn);
-
-- insn = emit_insn_before (gen_movsi (reg1, reg2), next);
-+ insn = emit_insn_before (gen_movsi (reg1dst, reg1src), next);
-
-- add_reg_note (next, REG_INC, reg1);
-+ add_reg_note (next, REG_INC, reg1dst);
-
- int newcost1 = insn_rtx_cost (set, true);
- int newcost2 = insn_rtx_cost (set2, true);
-
-- fprintf (stderr, "commute_add_move found, newcost: %d = %d + %d\n", newcost1 + newcost2, newcost1, newcost2);
-+ fprintf (stderr, "commute_add_move found, new cost: %d = %d + %d\n", newcost1 + newcost2, newcost1, newcost2);
-
-- //debug_rtx (insn);
-- //debug_rtx (next);
-+ debug_rtx (insn);
-+ debug_rtx (next);
-
- df_insn_rescan (insn);
- df_insn_rescan (next);
-@@ -889,13 +905,43 @@ const_cmp_to_sub (void)
- if (dst != cc0_rtx)
- continue;
-
-- fprintf (stderr, "cc0:");
-- debug_rtx (insn);
-+// fprintf (stderr, "cc0:");
-+// debug_rtx (insn);
- }
- #endif
- return change_count;
- }
-
-+static unsigned
-+elim_dead_assign (void)
-+{
-+ unsigned change_count = 0;
-+ for (unsigned index = 0; index + 1 < insns.size (); ++index)
-+ {
-+ rtx_insn * insn = insns[index];
-+ if (!NONJUMP_INSN_P(insn))
-+ continue;
++ SET_INSN_DELETED(insn);
+
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
++ insn = emit_insn_before (newinsn, next);
+
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+ if (!REG_P(dst) || !REG_P(src))
-+ continue;
++ add_reg_note (next, REG_INC, ii.get_dst_reg ());
+
-+ if (!infos[index].get (REGNO(dst)))
-+ {
-+ fprintf (stderr, "eliminate dead assignment to %d:", REGNO(dst));
-+ debug_rtx (insn);
-+ SET_INSN_DELETED(insn);
+ ++change_count;
+ }
++ else
++ cancel_changes (0);
+ }
+ return change_count;
+}
+
- /* Main entry point to the pass. */
- static unsigned int
- execute_bbb_optimizations (void)
-@@ -904,7 +950,6 @@ execute_bbb_optimizations (void)
- df_note_add_problem ();
- df_analyze ();
-
--// dump_insns ("bbb 0");
- filter_insns ();
-
- for (;;)
-@@ -925,15 +970,16 @@ execute_bbb_optimizations (void)
- if (const_cmp_to_sub ())
- done = 0, filter_insns ();
-
-+ if (elim_dead_assign ())
-+ done = 0, filter_insns ();
-+
- if (done)
- break;
- }
-
-- dump_insns ("bbb 1");
-+// dump_insns ("bbb 1");
- clear ();
-
-- dump_costs ();
--
- return 0;
- }
-
-@@ -964,7 +1010,7 @@ namespace
- virtual bool
- gate (function *)
- {
-- return TARGET_AMIGA;
-+ return TARGET_AMIGA && flag_bbb_opts;
- }
-
- virtual unsigned int
-
-From f5cd54a27e20a9ef7b1ec441fad9486216a87253 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 6 Apr 2017 13:41:46 +0200
-Subject: [PATCH 057/303] @N const_cmp_to_sub
-
----
- gcc/bbb-opts.c | 187 ++++++++++++++++++++++++++++++++++++++++++++-------------
- 1 file changed, 146 insertions(+), 41 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 48e2fa3fd255..44616bcabd6b 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -48,7 +48,9 @@
- #include <vector>
- #include <map>
-
--/* enough for m68k. */
-+/* Enough for m68k.
-+ * Why a class? Maybe extend it for general usage.
-+ */
- struct insn_info
- {
- unsigned mask;
-@@ -127,7 +129,7 @@ struct insn_info
- }
- };
-
--/* scan rtx for registers. */
-+/* scan rtx for registers and set the corresponding flags. */
- static void
- scanii (rtx x, insn_info & ii)
- {
-@@ -149,11 +151,17 @@ scanii (rtx x, insn_info & ii)
- }
- }
-
-+/*
-+ * Collect some data.
-+ */
- static std::vector<rtx_insn *> insns;
- static std::vector<rtx_insn *> jumps;
- static std::map<rtx_insn *, unsigned> insn2index;
- static std::vector<insn_info> infos;
-
-+/*
-+ * Reset collected data.
-+ */
- static void
- clear (void)
- {
-@@ -163,6 +171,10 @@ clear (void)
- infos.clear ();
- }
-
-+/*
-+ * Helper function to dump the code.
-+ * Sometimes used during debugging.
-+ */
- static void
- dump_insns (char const * name)
- {
-@@ -188,7 +200,7 @@ dump_insns (char const * name)
- * Create a filtered view of insns - keep only those to work with.
- */
- static void
--filter_insns ()
-+update_meta_data ()
- {
- rtx_insn *insn, *next;
- clear ();
-@@ -258,18 +270,11 @@ filter_insns ()
-
- if (CALL_P(insn))
- {
-- /* a call sets d0 and kills d1,a0,a1. */
-- if (ii.get (1))
-- fprintf (stderr, "d1 used after call\n");
-- if (ii.get (8))
-- fprintf (stderr, "a0 used after call\n");
-- if (ii.get (9))
-- fprintf (stderr, "a1 used after call\n");
--
-- ii.unset(0);
-- ii.unset(1);
-- ii.unset(8);
-- ii.unset(9);
-+ /* a call sets d0 and maybe also d1,a0,a1. */
-+ ii.unset (0);
-+ ii.unset (1);
-+ ii.unset (8);
-+ ii.unset (9);
-
- // FIXME: get the DECL and read attributes.
- // use regs depending on flag mregparm
-@@ -298,14 +303,13 @@ filter_insns ()
- ii |= infos[pos];
-
- // check for reg use
-- scanii(PATTERN(insn), ii);
-+ scanii (PATTERN (insn), ii);
-
- }
- infos[pos] = ii;
- continue;
- }
-
--
- rtx set = single_set (insn);
- if (set == 0)
- {
-@@ -313,13 +317,16 @@ filter_insns ()
- {
- rtx x = XEXP(pattern, 0);
- if (REG_P(x))
-- ii.set(REGNO(x));
-+ ii.set (REGNO(x));
- infos[pos] = ii;
- continue;
- }
-
-- fprintf (stderr, "##### ");
-- debug_rtx (insn);
-+ if (GET_CODE (pattern) != PARALLEL)
-+ {
-+ fprintf (stderr, "##### ");
-+ debug_rtx (insn);
-+ }
- scanii (pattern, ii);
- infos[pos] = ii;
- continue;
-@@ -501,7 +508,7 @@ propagate_moves ()
- {
- std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
- int fixup = 0;
-- fprintf (stderr, "need %d jump out fixups\n", jump_out.size ());
-+ fprintf (stderr, ": need %d jump out fixups\n", jump_out.size ());
-
- for (unsigned k = *i + 1; k != *j; ++k)
- {
-@@ -574,7 +581,7 @@ propagate_moves ()
- rtx_insn * after = insns[index + 1];
- rtx bset = single_set (before);
-
-- fprintf (stderr, "condition met, moving regs %d, %d\n", REGNO(srci), REGNO(dsti));
-+ fprintf (stderr, ": condition met, moving regs %d, %d\n", REGNO(srci), REGNO(dsti));
-
- /* Move in front of loop and mark as dead. */
- remove_insn (ii);
-@@ -607,7 +614,7 @@ propagate_moves ()
- /* add fixes if there were jumps out of the loop. */
- if (jump_out.size ())
- {
-- fprintf (stderr, "fixing %d jump outs\n", jump_out.size ());
-+ fprintf (stderr, ": fixing %d jump outs\n", jump_out.size ());
-
- for (unsigned k = 0; k < jump_out.size (); ++k)
- {
-@@ -698,7 +705,7 @@ opt_strcpy ()
-
- fprintf (
- stderr,
-- "condition met, removing compare and joining insns - omit reg %d\n", REGNO(dst));
-+ ": condition met, removing compare and joining insns - omit reg %d\n", REGNO(dst));
-
- for (link = REG_NOTES(x2reg); link; link = XEXP(link, 1))
- if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
-@@ -856,7 +863,7 @@ commute_add_move (void)
- int oldcost1 = insn_rtx_cost (set, true);
- int oldcost2 = insn_rtx_cost (set2, true);
-
-- fprintf (stderr, "commute_add_move found, old cost: %d = %d + %d\n", oldcost1 + oldcost2, oldcost1, oldcost2);
-+ fprintf (stderr, ": commute_add_move found, old cost: %d = %d + %d\n", oldcost1 + oldcost2, oldcost1, oldcost2);
-
- debug_rtx (insn);
- debug_rtx (next);
-@@ -875,7 +882,7 @@ commute_add_move (void)
- int newcost1 = insn_rtx_cost (set, true);
- int newcost2 = insn_rtx_cost (set2, true);
-
-- fprintf (stderr, "commute_add_move found, new cost: %d = %d + %d\n", newcost1 + newcost2, newcost1, newcost2);
-+ fprintf (stderr, ": commute_add_move found, new cost: %d = %d + %d\n", newcost1 + newcost2, newcost1, newcost2);
-
- debug_rtx (insn);
- debug_rtx (next);
-@@ -889,24 +896,122 @@ commute_add_move (void)
- return change_count;
- }
-
+/*
+ * Replace
+ *
@@ -9468,883 +3801,157 @@ index 48e2fa3fd255..44616bcabd6b 100755
+ (nil))))
+ *
+ */
- static unsigned
- const_cmp_to_sub (void)
- {
- unsigned change_count = 0;
- #if HAVE_cc0
-- for (unsigned index = 0; index + 1 < insns.size (); ++index)
-+ for (unsigned index = 1; index + 1 < insns.size (); ++index)
- {
- rtx_insn * insn = insns[index];
-- rtx set = single_set (insn);
-- if (!set)
-+ rtx seti = single_set (insn);
-+ if (!seti)
- continue;
-
-- rtx dst = SET_DEST(set);
-- if (dst != cc0_rtx)
-+ rtx dsti = SET_DEST(seti);
-+ if (dsti != cc0_rtx)
-+ continue;
-+
-+ rtx srci = SET_SRC(seti);
-+ if (GET_CODE(srci) != COMPARE)
-+ continue;
-+
-+ rtx left = XEXP(srci, 0);
-+ rtx right = XEXP(srci, 1);
-+ if (!REG_P(left) || !REG_P(right))
- continue;
-
--// fprintf (stderr, "cc0:");
--// debug_rtx (insn);
-+ if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
-+ continue;
-+
-+ fprintf (stderr, ": found reg-reg compare with both dead\n");
++static unsigned
++opt_const_cmp_to_sub (void)
++{
++ unsigned change_count = 0;
++#if HAVE_cc0
++ if (infos.size () < 2)
++ return change_count;
+
-+ // maybe add a search?
-+ rtx_insn * prev = insns[index - 1];
-+ rtx setp = single_set (prev);
-+ if (!setp)
-+ continue;
++ unsigned lastsub = 0;
++ for (unsigned index = infos.size () - 2; index > 0; --index)
++ {
++ insn_info & i1 = infos[index];
+
-+ rtx dstp = SET_DEST(setp);
-+ if (!REG_P(dstp) || dstp != left)
++ /* we wan't a compare or tst insn, */
++ if (!i1.is_compare ())
+ continue;
+
-+ rtx srcp = SET_SRC(setp);
-+ if (!CONST_INT_P(srcp))
++ if (GET_MODE_SIZE(i1.get_mode()) > 4 || !i1.is_dst_reg () || REGNO(i1.get_dst_reg()) > 7)
+ continue;
+
-+ int intval = -INTVAL(srcp);
-+ if (intval < -8 || intval > 7)
++ /* src must be a reg dead register with a constant - or a #0 */
++ if (!i1.get_src_reg () && (!i1.is_src_const () || i1.get_src_op () == PLUS))
+ continue;
+
-+ enum machine_mode mode = GET_MODE(dstp);
-+ rtx reg = dstp == left ? right : left;
-+ rtx plus = gen_rtx_PLUS(mode, reg, gen_rtx_CONST_INT(mode, intval));
-+
-+ SET_SRC(setp) = plus;
-+ SET_DEST(setp) = reg;
-+
-+ int num_clobbers_to_add = 0;
-+ int insn_code_number = recog (PATTERN (prev), prev, &num_clobbers_to_add);
++ /* allow an alive reg, if life ends at previous handled sub. */
++ int lastsubval = 0;
++ if (lastsub == index + 3)
++ {
++ insn_info & pp = infos[lastsub];
++ if (pp.get_dst_regno () != i1.get_dst_regno ())
++ continue;
++ lastsubval = pp.get_src_intval ();
+
-+ SET_SRC(setp) = srcp;
-+ SET_DEST(setp) = dstp;
++ // but still check for usage after this jump
++ j2l_iterator l = jump2label.find (index + 2);
++ if (l == jump2label.end ())
++ continue;
+
-+ if (insn_code_number < 0)
++ insn_info & label = infos[l->second + 1];
++ if (label.is_use (i1.get_dst_regno ()))
++ continue;
++ }
++ else if (!is_reg_dead (i1.get_dst_regno (), index))
+ continue;
+
-+ debug_rtx(prev);
-+ debug_rtx(insn);
-+
-+ // also convert current statement to cmp #0, reg
-+ SET_INSN_DELETED(insn);
-+ rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, reg, gen_rtx_CONST_INT(mode, 0)));
-+ insn = emit_insn_after(neu, prev);
-+ add_reg_note (insn, REG_DEAD, reg);
++ insn_info & i0 = infos[index - 1];
++ int intval = 0;
++ /* compare with register - check previous insn for load with constant. */
++ if (i1.is_src_reg ())
++ {
++ if (!is_reg_dead (i1.get_src_regno (), index))
++ continue;
+
-+ SET_INSN_DELETED(prev);
-+ neu = gen_rtx_SET(reg, plus);
-+ prev = emit_insn_before(neu, insn);
++ if (GET_MODE_SIZE(i0.get_mode()) > 4)
++ continue;
+
-+ int omitted_regno = REGNO(dstp == left ? left: right);
-+ if (!(df->hard_regs_live_count[omitted_regno] -= 2))
-+ df_set_regs_ever_live (omitted_regno, false);
++ if (!i0.is_dst_reg () || !i0.is_src_const () || i0.get_src_op ())
++ continue;
+
-+ fprintf (stderr, ": replaced reg-reg compare with sub\n");
-+ debug_rtx(prev);
-+ debug_rtx(insn);
++ if (i0.get_dst_regno () != i1.get_src_regno ())
++ continue;
+
-+ if (dstp != left)
-+ {
-+ // invert all conditions using this statement.
++ intval = -i0.get_src_intval ();
++ if (intval < -8 || intval > 7)
++ continue;
+
++ /* is the next sub value in range? */
++ if (lastsub == index + 3 && (lastsubval - intval < -8 || lastsubval - intval > 7))
++ continue;
+ }
+
++ /* next insn must be the jump. */
++ insn_info & i2 = infos[index + 1];
++ if (!i2.is_jump ())
++ continue;
+
-+ ++change_count;
- }
- #endif
- return change_count;
-@@ -933,7 +1038,7 @@ elim_dead_assign (void)
-
- if (!infos[index].get (REGNO(dst)))
- {
-- fprintf (stderr, "eliminate dead assignment to %d:", REGNO(dst));
-+ fprintf (stderr, ": eliminate dead assignment to %d:", REGNO(dst));
- debug_rtx (insn);
- SET_INSN_DELETED(insn);
- ++change_count;
-@@ -950,28 +1055,28 @@ execute_bbb_optimizations (void)
- df_note_add_problem ();
- df_analyze ();
-
-- filter_insns ();
-+ update_meta_data ();
-
- for (;;)
- {
- int done = 1;
- if (propagate_moves ())
-- done = 0, filter_insns ();
-+ done = 0, update_meta_data ();
-
- if (offset_2_autoinc ())
-- done = 0, filter_insns ();
-+ done = 0, update_meta_data ();
-
- if (opt_strcpy ())
-- done = 0, filter_insns ();
-+ done = 0, update_meta_data ();
-
- if (commute_add_move ())
-- done = 0, filter_insns ();
-+ done = 0, update_meta_data ();
-
- if (const_cmp_to_sub ())
-- done = 0, filter_insns ();
-+ done = 0, update_meta_data ();
-
- if (elim_dead_assign ())
-- done = 0, filter_insns ();
-+ done = 0, update_meta_data ();
-
- if (done)
- break;
-
-From 485cc891b48af316e84f77e6142a0c28b80c596d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 6 Apr 2017 22:05:20 +0200
-Subject: [PATCH 058/303] @N const_cmp_to_sub seems working
-
----
- gcc/bbb-opts.c | 249 ++++++++++++++++++++++++++++++++++++++++++++-------------
- 1 file changed, 192 insertions(+), 57 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 44616bcabd6b..8a98fbfaad7c 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -50,45 +50,64 @@
-
- /* Enough for m68k.
- * Why a class? Maybe extend it for general usage.
-+ *
-+ * Track use & def separate to determine starting points.
- */
- struct insn_info
- {
-- unsigned mask;
-+ unsigned _use;
-+ unsigned _def;
-
- insn_info () :
-- mask (0)
-+ _use (0), _def (0)
- {
- }
-
- inline void
- reset ()
- {
-- mask = 0;
-+ _use = 0;
-+ _def = 0;
- }
-
- inline void
-- set (int regno)
-+ use (int regno)
- {
-- mask |= 1 << regno;
-+ _use |= 1 << regno;
-+ }
-+
-+ inline void
-+ def (int regno)
-+ {
-+ _use |= 1 << regno;
-+ _def |= 1 << regno;
- }
-
- inline void
- unset (int regno)
- {
-- mask &= ~(1 << regno);
-+ _use &= ~(1 << regno);
-+ _def &= ~(1 << regno);
- }
-
- inline bool
-- get (int regno)
-+ is_use (int regno)
- {
-- return (mask & (1 << regno)) != 0;
-+ return (_use & (1 << regno)) != 0;
-+ }
++ rtx jmppattern = single_set (i2.get_insn ());
++ if (!jmppattern)
++ continue;
+
-+ inline bool
-+ is_def (int regno)
-+ {
-+ return (_def & (1 << regno)) != 0;
- }
-
- inline insn_info
- operator | (insn_info const & o) const
- {
- insn_info t;
-- t.mask = mask | o.mask;
-+ t._use = _use | o._use;
-+ t._def = _def | o._def;
- return t;
- }
-
-@@ -96,46 +115,67 @@ struct insn_info
- operator & (insn_info const & o) const
- {
- insn_info t;
-- t.mask = mask & o.mask;
-+ t._use = _use & o._use;
-+ t._def = _def & o._def;
- return t;
- }
-
- inline insn_info &
- operator |= (insn_info const & o)
- {
-- mask |= o.mask;
-+ _use |= o._use;
-+ _def |= o._def;
- return *this;
- }
-
- inline insn_info &
- operator &= (insn_info const & o)
- {
-- mask &= o.mask;
-+ _use &= o._use;
-+ _def &= o._def;
- return *this;
- }
-
- inline bool
- operator == (insn_info const & o)
- {
-- return mask == o.mask;
-+ return _use == o._use;
- }
-
- inline insn_info
- operator ~ () const
- {
- insn_info t;
-- t.mask = ~mask;
-+ t._use = ~_use;
-+ t._def = ~_def;
- return t;
- }
++ rtx jmpsrc = XEXP(jmppattern, 1);
++ if (GET_CODE(jmpsrc) != IF_THEN_ELSE)
++ continue;
+
-+ inline bool contains(insn_info const & o) const {
-+ if (o._def & ~_def)
-+ return false;
-+ if (o._use & ~_use)
-+ return false;
-+ return true;
-+ }
++ rtx condition = XEXP(jmpsrc, 0);
++ RTX_CODE code = GET_CODE(condition);
++ if (code != EQ && code != NE)
++ continue;
+
-+ void
-+ scan (rtx);
- };
-
- /* scan rtx for registers and set the corresponding flags. */
--static void
--scanii (rtx x, insn_info & ii)
-+void
-+insn_info::scan (rtx x)
- {
- if (REG_P(x))
- {
-- ii.set (REGNO(x));
-+ use (REGNO(x));
-+ return;
-+ }
++ if (intval)
++ {
++ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
++ /* create the sub statement. */
++ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), intval));
+
-+ if (x == cc0_rtx)
-+ {
-+ use (FIRST_PSEUDO_REGISTER);
- return;
- }
-
-@@ -144,10 +184,10 @@ scanii (rtx x, insn_info & ii)
- for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
-- scanii (XEXP(x, i), ii);
-+ scan (XEXP(x, i));
- else if (fmt[i] == 'E')
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-- scanii (XVECEXP(x, i, j), ii);
-+ scan (XVECEXP(x, i, j));
- }
- }
-
-@@ -171,6 +211,23 @@ clear (void)
- infos.clear ();
- }
-
-+static bool is_reg_dead(unsigned regno, unsigned pos)
-+{
-+ if (pos >= infos.size())
-+ return true;
++ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub));
+
-+ insn_info & ii0 = infos[pos++];
-+ if (!ii0.is_use(regno))
-+ return true;
++ if (insn_invalid_p (subinsn, 0))
++ continue;
+
-+ if (pos >= infos.size())
-+ return true;
++ /* delete move #x,dy. */
++ SET_INSN_DELETED(i0.get_insn ())
++ /* delete cmp dx,dy */
++ SET_INSN_DELETED(i1.get_insn ());
++ /* add a cmp #0 - to be removed in final() */
+
-+ insn_info & ii1 = infos[pos];
++ /* convert cmp/tst into sub */
++ subinsn = emit_insn_before (PATTERN (subinsn), i1.get_insn ());
++ i1.set_insn (subinsn);
+
-+ return !ii1.is_use(regno);
-+}
++ rtx neu = gen_rtx_SET(cc0_rtx,
++ gen_rtx_COMPARE (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), 0)));
+
- /*
- * Helper function to dump the code.
- * Sometimes used during debugging.
-@@ -184,12 +241,15 @@ dump_insns (char const * name)
- insn_info & ii = infos[i];
-
- for (int j = 0; j < 8; ++j)
-- if (ii.get (j))
-- fprintf (stderr, "d%d ", j);
-+ if (ii.is_use (j))
-+ fprintf (stderr, ii.is_def (j) ? "*d%d " : "d%d ", j);
-
- for (int j = 8; j < 16; ++j)
-- if (ii.get (j))
-- fprintf (stderr, "a%d ", j - 8);
-+ if (ii.is_use (j))
-+ fprintf (stderr, ii.is_def (j) ? "*a%d " : "a%d ", j - 8);
-+
-+ if (ii.is_use (FIRST_PSEUDO_REGISTER))
-+ fprintf (stderr, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc ");
-
- fprintf (stderr, "\t");
- debug_rtx (insns[i]);
-@@ -246,7 +306,7 @@ update_meta_data ()
- {
- rtx_insn * insn = insns[pos];
-
-- if (pass && ii == infos[pos])
-+ if (pass && infos[pos].contains(ii))
- break;
-
- ii |= infos[pos];
-@@ -276,16 +336,16 @@ update_meta_data ()
- ii.unset (8);
- ii.unset (9);
-
-- // FIXME: get the DECL and read attributes.
-+ // FIXME: isuse the DECL and read attributes.
- // use regs depending on flag mregparm
- for (int i = 0; i < amigaos_regparm; ++i)
- {
-- ii.set (i);
-- ii.set (i + 8);
-+ ii.use (i);
-+ ii.use (i + 8);
- }
-
- // check for reg use
-- scanii (pattern, ii);
-+ ii.scan (pattern);
-
- infos[pos] = ii;
- continue;
-@@ -296,14 +356,14 @@ update_meta_data ()
- if (ANY_RETURN_P(pattern))
- {
- ii.reset ();
-- ii.set (0);
-+ ii.use (0);
- }
- else
- {
- ii |= infos[pos];
-
- // check for reg use
-- scanii (PATTERN (insn), ii);
-+ ii.scan (PATTERN (insn));
-
- }
- infos[pos] = ii;
-@@ -317,7 +377,7 @@ update_meta_data ()
- {
- rtx x = XEXP(pattern, 0);
- if (REG_P(x))
-- ii.set (REGNO(x));
-+ ii.use (REGNO(x));
- infos[pos] = ii;
- continue;
- }
-@@ -327,7 +387,7 @@ update_meta_data ()
- fprintf (stderr, "##### ");
- debug_rtx (insn);
- }
-- scanii (pattern, ii);
-+ ii.scan (pattern);
- infos[pos] = ii;
- continue;
- }
-@@ -341,13 +401,23 @@ update_meta_data ()
- insn_info use;
- insn_info def;
-
-- scanii (src, use);
-+ use.scan (src);
- if (REG_P(dst))
-- def.set (REGNO(dst));
-+ def.def (REGNO(dst));
-+ else if (dst == cc0_rtx)
-+ def.def (FIRST_PSEUDO_REGISTER);
- else
-- scanii (dst, use);
-+ use.scan (dst);
-
-- infos[pos] = use | ii;
-+ if (dst != cc0_rtx)
-+ {
-+ CC_STATUS_INIT;
-+ NOTICE_UPDATE_CC(PATTERN (insn), insn);
-+ if (cc_status.value1 || cc_status.value2)
-+ def.def (FIRST_PSEUDO_REGISTER);
-+ }
++ emit_insn_before (neu, i2.get_insn ());
+
-+ infos[pos] = def | use | ii;
-
- ii &= ~def;
- ii |= use;
-@@ -778,15 +848,15 @@ offset_2_autoinc (void)
- if (!NONJUMP_INSN_P(insn))
- continue;
-
-- rtx set = single_set (insn);
-- if (!set)
-+ rtx use = single_set (insn);
-+ if (!use)
- continue;
-
-- rtx reg = SET_DEST(set);
-+ rtx reg = SET_DEST(use);
- if (!REG_P(reg))
- continue;
-
-- rtx val = SET_SRC(set);
-+ rtx val = SET_SRC(use);
-
- // fprintf(stderr, "possible start for offset_2_autoinc\n");
- // //debug_rtx(insn);
-@@ -882,7 +952,8 @@ commute_add_move (void)
- int newcost1 = insn_rtx_cost (set, true);
- int newcost2 = insn_rtx_cost (set2, true);
-
-- fprintf (stderr, ": commute_add_move found, new cost: %d = %d + %d\n", newcost1 + newcost2, newcost1, newcost2);
-+ fprintf (stderr, ": commute_add_move found, new cost: %d = %d + %d\n", newcost1 + newcost2, newcost1,
-+ newcost2);
-
- debug_rtx (insn);
- debug_rtx (next);
-@@ -944,10 +1015,14 @@ const_cmp_to_sub (void)
- if (!REG_P(left) || !REG_P(right))
- continue;
-
-- if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
-- continue;
-+// if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
-+// continue;
-
-- fprintf (stderr, ": found reg-reg compare with both dead\n");
-+ if (!is_reg_dead(REGNO(left), index) || !is_reg_dead(REGNO(right), index))
-+ continue;
++ log ("(c) const_cmp_to_sub replaced %s == %s (%d) with sub %d,%s\n", reg_names[i1.get_dst_regno ()],
++ reg_names[i0.get_dst_regno ()],
++ -intval, -intval, reg_names[i1.get_dst_regno ()]);
+
-+ fprintf (stderr, ": found reg-reg compare with both dead: %d %d\n",
-+ is_reg_dead(REGNO(left), index), is_reg_dead(REGNO(right), index));
-
- // maybe add a search?
- rtx_insn * prev = insns[index - 1];
-@@ -956,7 +1031,7 @@ const_cmp_to_sub (void)
- continue;
-
- rtx dstp = SET_DEST(setp);
-- if (!REG_P(dstp) || dstp != left)
-+ if (!REG_P(dstp))
- continue;
-
- rtx srcp = SET_SRC(setp);
-@@ -969,7 +1044,7 @@ const_cmp_to_sub (void)
-
- enum machine_mode mode = GET_MODE(dstp);
- rtx reg = dstp == left ? right : left;
-- rtx plus = gen_rtx_PLUS(mode, reg, gen_rtx_CONST_INT(mode, intval));
-+ rtx plus = gen_rtx_PLUS(mode, reg, gen_rtx_CONST_INT (mode, intval));
-
- SET_SRC(setp) = plus;
- SET_DEST(setp) = reg;
-@@ -983,33 +1058,93 @@ const_cmp_to_sub (void)
- if (insn_code_number < 0)
- continue;
-
-- debug_rtx(prev);
-- debug_rtx(insn);
-+ debug_rtx (prev);
-+ debug_rtx (insn);
-
- // also convert current statement to cmp #0, reg
- SET_INSN_DELETED(insn);
- rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, reg, gen_rtx_CONST_INT(mode, 0)));
-- insn = emit_insn_after(neu, prev);
-+ insn = emit_insn_after (neu, prev);
- add_reg_note (insn, REG_DEAD, reg);
-
- SET_INSN_DELETED(prev);
- neu = gen_rtx_SET(reg, plus);
-- prev = emit_insn_before(neu, insn);
-+ prev = emit_insn_before (neu, insn);
-
-- int omitted_regno = REGNO(dstp == left ? left: right);
-- if (!(df->hard_regs_live_count[omitted_regno] -= 2))
-- df_set_regs_ever_live (omitted_regno, false);
-+// urks - unknown side effects
-+// int omitted_regno = REGNO(dstp);
-+// if (!(df->hard_regs_live_count[omitted_regno] -= 2))
-+// df_set_regs_ever_live (omitted_regno, false);
-
- fprintf (stderr, ": replaced reg-reg compare with sub\n");
-- debug_rtx(prev);
-- debug_rtx(insn);
-+ debug_rtx (prev);
-+ debug_rtx (insn);
-
- if (dstp != left)
- {
- // invert all conditions using this statement.
-+ std::vector<unsigned> todo;
-+ std::vector<unsigned> done;
-+ done.resize(insns.size());
-+ todo.push_back (index + 1);
-
-- }
-+ while (todo.size ())
++ if (index + 3 == lastsub)
+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
-+
-+ if (done[pos])
-+ continue;
-
-+ done[pos] = 1;
-+
-+ if (infos[pos].is_def (FIRST_PSEUDO_REGISTER))
-+ continue;
-+
-+ if (pos + 1 < infos.size ())
-+ todo.push_back (pos + 1);
-+
-+ rtx_insn * patchme = insns[pos];
-+ if (!JUMP_P(insn))
-+ continue;
-+
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(patchme));
-+ if (j != insn2index.end ())
-+ todo.push_back (j->second);
++ /* patch previous sub - or even a compare. */
++ insn_info & pp = infos[lastsub];
+
-+ rtx jmppattern = PATTERN (patchme);
++ int diff = lastsubval - intval;
++ rtx c = gen_rtx_CONST_INT (i1.get_mode (), diff);
+
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
++ if (pp.is_compare ())
+ {
-+ rtx condition = XEXP(jmpsrc, 0);
-+ RTX_CODE code = GET_CODE(condition);
-+ RTX_CODE newcode = code;
-+ if (code == GE)
-+ newcode = LE;
-+ else if (code == GT)
-+ newcode = LT;
-+ else if (code == LT)
-+ newcode = GT;
-+ else if (code == LE)
-+ newcode = GE;
-+ else if (code == GEU)
-+ newcode = LEU;
-+ else if (code == GTU)
-+ newcode = LTU;
-+ else if (code == LTU)
-+ newcode = GTU;
-+ else if (code == LEU)
-+ newcode = GEU;
-+
-+ if (code != newcode)
-+ {
-+ fprintf (stderr, ": patch jcc %d -> %d\n", code, newcode);
-+ XEXP(jmpsrc, 0) = gen_rtx_fmt_ee(newcode, VOIDmode, XEXP(condition, 0), XEXP(condition, 1));
-+ }
++ /* still a compare with 0 -> insert the sub. */
++ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
++ /* create the sub statement. */
++ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, c);
++ rtx set = gen_rtx_SET(copyreg, sub);
++ emit_insn_before (set, pp.get_insn ());
++ }
++ else
++ {
++ /* modify the sub. */
++ XEXP(SET_SRC(PATTERN(pp.get_insn())), 1) = c;
+ }
+ }
++
++ lastsub = index;
++ ++change_count;
+ }
-
- ++change_count;
- }
-@@ -1036,7 +1171,7 @@ elim_dead_assign (void)
- if (!REG_P(dst) || !REG_P(src))
- continue;
-
-- if (!infos[index].get (REGNO(dst)))
-+ if (!infos[index].is_use (REGNO(dst)))
- {
- fprintf (stderr, ": eliminate dead assignment to %d:", REGNO(dst));
- debug_rtx (insn);
-
-From 9967eed30e2e8f28bb48aa5a39d1cd578d4e0a7a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 7 Apr 2017 04:03:53 +0200
-Subject: [PATCH 059/303] @B avoid illegal insns
-
----
- gcc/bbb-opts.c | 188 ++++++++++++++++++++++++++++++++++++++++-----------------
- 1 file changed, 132 insertions(+), 56 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 8a98fbfaad7c..d9e77c53856d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -79,7 +79,6 @@ struct insn_info
- inline void
- def (int regno)
- {
-- _use |= 1 << regno;
- _def |= 1 << regno;
- }
-
-@@ -151,7 +150,9 @@ struct insn_info
- return t;
- }
-
-- inline bool contains(insn_info const & o) const {
-+ inline bool
-+ contains (insn_info const & o) const
-+ {
- if (o._def & ~_def)
- return false;
- if (o._use & ~_use)
-@@ -211,21 +212,22 @@ clear (void)
- infos.clear ();
- }
-
--static bool is_reg_dead(unsigned regno, unsigned pos)
-+static bool
-+is_reg_dead (unsigned regno, unsigned pos)
- {
-- if (pos >= infos.size())
-+ if (pos >= infos.size ())
- return true;
-
- insn_info & ii0 = infos[pos++];
-- if (!ii0.is_use(regno))
-+ if (!ii0.is_use (regno))
- return true;
-
-- if (pos >= infos.size())
-+ if (pos >= infos.size ())
- return true;
-
- insn_info & ii1 = infos[pos];
-
-- return !ii1.is_use(regno);
-+ return !ii1.is_use (regno);
- }
-
- /*
-@@ -274,7 +276,6 @@ update_meta_data ()
-
- if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
- {
-- // debug_rtx (insn);
- if (JUMP_P(insn))
- jumps.push_back (insn);
-
-@@ -306,7 +307,7 @@ update_meta_data ()
- {
- rtx_insn * insn = insns[pos];
-
-- if (pass && infos[pos].contains(ii))
-+ if (pass && infos[pos].contains (ii))
- break;
-
- ii |= infos[pos];
-@@ -578,7 +579,6 @@ propagate_moves ()
- {
- std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
- int fixup = 0;
-- fprintf (stderr, ": need %d jump out fixups\n", jump_out.size ());
-
- for (unsigned k = *i + 1; k != *j; ++k)
- {
-@@ -651,7 +651,8 @@ propagate_moves ()
- rtx_insn * after = insns[index + 1];
- rtx bset = single_set (before);
-
-- fprintf (stderr, ": condition met, moving regs %d, %d\n", REGNO(srci), REGNO(dsti));
-+ fprintf (stderr, ":bbb: propagate_moves condition met, moving regs %d, %d\n",
-+ REGNO(srci), REGNO(dsti));
-
- /* Move in front of loop and mark as dead. */
- remove_insn (ii);
-@@ -684,7 +685,7 @@ propagate_moves ()
- /* add fixes if there were jumps out of the loop. */
- if (jump_out.size ())
- {
-- fprintf (stderr, ": fixing %d jump outs\n", jump_out.size ());
-+ fprintf (stderr, ":bbb: propagate_moves fixing %d jump outs\n", jump_out.size ());
-
- for (unsigned k = 0; k < jump_out.size (); ++k)
- {
-@@ -763,7 +764,7 @@ opt_strcpy ()
- SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
- insn_code_number = recog (PATTERN (reg2x), reg2x, &num_clobbers_to_add);
-
-- if (insn_code_number < 0)
-+ if (insn_code_number < 0 || !check_asm_operands (reg2x))
- {
- /* restore register. */
- SET_SRC(single_set(reg2x)) = SET_DEST(single_set (x2reg));
-@@ -775,7 +776,8 @@ opt_strcpy ()
-
- fprintf (
- stderr,
-- ": condition met, removing compare and joining insns - omit reg %d\n", REGNO(dst));
-+ ":bbb: opt_strcpy condition met, removing compare and joining insns - omit reg %d\n",
-+ REGNO(dst));
-
- for (link = REG_NOTES(x2reg); link; link = XEXP(link, 1))
- if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
-@@ -930,14 +932,6 @@ commute_add_move (void)
- if (!REG_P(memreg) || REGNO(memreg) != REGNO(reg1src))
- continue;
-
-- int oldcost1 = insn_rtx_cost (set, true);
-- int oldcost2 = insn_rtx_cost (set2, true);
--
-- fprintf (stderr, ": commute_add_move found, old cost: %d = %d + %d\n", oldcost1 + oldcost2, oldcost1, oldcost2);
--
-- debug_rtx (insn);
-- debug_rtx (next);
--
- rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1dst);
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
-@@ -949,14 +943,7 @@ commute_add_move (void)
-
- add_reg_note (next, REG_INC, reg1dst);
-
-- int newcost1 = insn_rtx_cost (set, true);
-- int newcost2 = insn_rtx_cost (set2, true);
--
-- fprintf (stderr, ": commute_add_move found, new cost: %d = %d + %d\n", newcost1 + newcost2, newcost1,
-- newcost2);
--
-- debug_rtx (insn);
-- debug_rtx (next);
-+ fprintf (stderr, ":bbb: commute_add_move found\n");
-
- df_insn_rescan (insn);
- df_insn_rescan (next);
-@@ -1018,11 +1005,15 @@ const_cmp_to_sub (void)
- // if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
- // continue;
-
-- if (!is_reg_dead(REGNO(left), index) || !is_reg_dead(REGNO(right), index))
-- continue;
-+ // TODO
-+ // FEATURE: check if the next uses are also a add/sub
-+ // then maybe that add/sub can be adjusted too
-
-- fprintf (stderr, ": found reg-reg compare with both dead: %d %d\n",
-- is_reg_dead(REGNO(left), index), is_reg_dead(REGNO(right), index));
-+ if (!is_reg_dead (REGNO(left), index) || !is_reg_dead (REGNO(right), index))
-+ continue;
++ }
++#endif
++ return change_count;
++}
+
-+ fprintf (stderr, ":bbb: found reg-reg compare with both dead: %d %d\n", is_reg_dead (REGNO(left), index),
-+ is_reg_dead (REGNO(right), index));
-
- // maybe add a search?
- rtx_insn * prev = insns[index - 1];
-@@ -1051,6 +1042,8 @@ const_cmp_to_sub (void)
-
- int num_clobbers_to_add = 0;
- int insn_code_number = recog (PATTERN (prev), prev, &num_clobbers_to_add);
-+ if (insn_code_number >= 0 && !check_asm_operands (prev))
-+ insn_code_number = -1;
-
- SET_SRC(setp) = srcp;
- SET_DEST(setp) = dstp;
-@@ -1058,9 +1051,6 @@ const_cmp_to_sub (void)
- if (insn_code_number < 0)
- continue;
-
-- debug_rtx (prev);
-- debug_rtx (insn);
--
- // also convert current statement to cmp #0, reg
- SET_INSN_DELETED(insn);
- rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, reg, gen_rtx_CONST_INT(mode, 0)));
-@@ -1076,16 +1066,14 @@ const_cmp_to_sub (void)
- // if (!(df->hard_regs_live_count[omitted_regno] -= 2))
- // df_set_regs_ever_live (omitted_regno, false);
-
-- fprintf (stderr, ": replaced reg-reg compare with sub\n");
-- debug_rtx (prev);
-- debug_rtx (insn);
-+ fprintf (stderr, ":bbb: const_cmp_to_sub replaced reg-reg compare with sub\n");
-
- if (dstp != left)
- {
- // invert all conditions using this statement.
- std::vector<unsigned> todo;
- std::vector<unsigned> done;
-- done.resize(insns.size());
-+ done.resize (insns.size ());
- todo.push_back (index + 1);
-
- while (todo.size ())
-@@ -1139,7 +1127,7 @@ const_cmp_to_sub (void)
-
- if (code != newcode)
- {
-- fprintf (stderr, ": patch jcc %d -> %d\n", code, newcode);
-+ fprintf (stderr, ":bbb: patch jcc %d -> %d\n", code, newcode);
- XEXP(jmpsrc, 0) = gen_rtx_fmt_ee(newcode, VOIDmode, XEXP(condition, 0), XEXP(condition, 1));
- }
- }
-@@ -1173,8 +1161,7 @@ elim_dead_assign (void)
-
- if (!infos[index].is_use (REGNO(dst)))
- {
-- fprintf (stderr, ": eliminate dead assignment to %d:", REGNO(dst));
-- debug_rtx (insn);
-+ fprintf (stderr, ":bbb: elim_dead_assign to %d\n", REGNO(dst));
- SET_INSN_DELETED(insn);
- ++change_count;
- }
-@@ -1182,6 +1169,86 @@ elim_dead_assign (void)
- return change_count;
- }
-
+/*
+ * rare and only little gain - but :-)
+ lea (-1,a0),a1
@@ -10356,1117 +3963,179 @@ index 8a98fbfaad7c..d9e77c53856d 100755
+ add.l d1,a1
+ */
+static unsigned
-+merge_add (void)
++opt_merge_add (void)
+{
+ unsigned change_count = 0;
-+ for (unsigned index = 0; index + 2 < insns.size (); ++index)
++ for (unsigned index = 0; index + 2 < infos.size (); ++index)
+ {
-+ rtx_insn * ins1 = insns[index];
-+ rtx_insn * ins2 = insns[index + 1];
-+ rtx_insn * ins3 = insns[index + 2];
-+ if (!NONJUMP_INSN_P(ins1) && !NONJUMP_INSN_P(ins2) && !NONJUMP_INSN_P(ins3))
++ insn_info & ii0 = infos[index];
++ insn_info & ii1 = infos[index + 1];
++ insn_info & ii2 = infos[index + 2];
++
++ if (!ii2.is_dst_reg ())
++ {
++ index += 2;
++ continue;
++ }
++
++ if (!ii1.is_dst_reg ())
++ {
++ ++index;
++ continue;
++ }
++
++ if (!ii0.is_dst_reg () || ii0.get_src_op () != PLUS || ii1.get_src_op () != PLUS || ii2.get_src_op () != PLUS)
+ continue;
+
-+ rtx set1 = single_set (ins1);
-+ rtx set2 = single_set (ins2);
-+ rtx set3 = single_set (ins3);
-+ if (!set1 || !set2 || !set3)
++ if (!ii0.is_src_const () || !ii2.is_src_const () || ii0.get_src_intval () != ii2.get_src_intval ())
+ continue;
+
-+ rtx dst1 = SET_DEST(set1);
-+ rtx dst2 = SET_DEST(set2);
-+ rtx dst3 = SET_DEST(set3);
-+ if (!REG_P(dst1) || !REG_P(dst2) || !REG_P(dst3))
++ if (ii0.get_dst_regno () != ii1.get_dst_regno () || ii1.get_src_regno () != ii2.get_dst_regno ())
+ continue;
+
++ rtx_insn * insn1 = ii1.get_insn ();
++
+ CC_STATUS_INIT;
-+ NOTICE_UPDATE_CC(PATTERN (ins2), ins2);
++ NOTICE_UPDATE_CC(PATTERN (insn1), insn1);
+ if (cc_status.value1 || cc_status.value2)
+ continue;
+
-+ rtx src1 = SET_SRC(set1);
-+ rtx src2 = SET_SRC(set2);
-+ rtx src3 = SET_SRC(set3);
-+ if (GET_CODE(src1) != PLUS || GET_CODE(src2) != PLUS || GET_CODE(src3) != PLUS)
-+ continue;
-+
-+ rtx l1 = XEXP(src1, 0);
-+ rtx l2 = XEXP(src2, 0);
-+ rtx l3 = XEXP(src3, 0);
++ log ("(m) %d: merge_add applied\n", index);
+
-+ rtx r1 = XEXP(src1, 1);
-+ rtx r2 = XEXP(src2, 1);
-+ rtx r3 = XEXP(src3, 1);
-+ if (!CONST_INT_P(r1) || !REG_P(r2) || !CONST_INT_P(r3))
-+ continue;
++ rtx_insn * insn0 = ii0.get_insn ();
++ rtx set = PATTERN (insn0);
+
-+ if (REGNO(dst1) != REGNO(dst2) || REGNO(r2) != REGNO(dst3))
-+ continue;
++ // convert lea (-1,a0),a1 into move.l a0,a1
++ rtx_insn * newins0 = make_insn_raw (gen_rtx_SET(XEXP(set, 0), XEXP(XEXP(set, 1), 0)));
++ add_insn_after (newins0, insn0, 0);
++ SET_INSN_DELETED(insn0);
++ // update infos accordingly
++ ii0.plus_to_move (newins0);
+
-+ fprintf (stderr, ": merge_add pattern found\n");
++ rtx_insn * insn2 = ii2.get_insn ();
++ rtx_insn * newins1 = make_insn_raw (PATTERN (insn1));
++ add_insn_after (newins1, insn2, 0);
++ SET_INSN_DELETED(insn1);
++ ii1.swap_adds (newins1, ii2);
+
-+ SET_SRC(set1) = l1;
-+ remove_insn (ins2);
-+ add_insn_after (ins2, ins3, 0);
++ ++change_count;
+ }
+ return change_count;
+}
+
-+/*
-+ * Always prefer lower register numbers within the class.
-+ */
++/* Update the insn_infos to 'know' the sp offset. */
+static unsigned
-+bb_reg_rename(void)
-+{
-+ unsigned change_count = 0;
-+ for (unsigned index = 0; index < insns.size (); ++index)
-+ {
-+ }
-+ return change_count;
-+}
-+
- /* Main entry point to the pass. */
- static unsigned int
- execute_bbb_optimizations (void)
-@@ -1195,22 +1262,31 @@ execute_bbb_optimizations (void)
- for (;;)
- {
- int done = 1;
-- if (propagate_moves ())
-- done = 0, update_meta_data ();
-+ for (;;)
-+ {
-+ if (propagate_moves ())
-+ done = 0, update_meta_data ();
-
-- if (offset_2_autoinc ())
-- done = 0, update_meta_data ();
-+ if (offset_2_autoinc ())
-+ done = 0, update_meta_data ();
-
-- if (opt_strcpy ())
-- done = 0, update_meta_data ();
-+ if (opt_strcpy ())
-+ done = 0, update_meta_data ();
-
-- if (commute_add_move ())
-- done = 0, update_meta_data ();
-+ if (commute_add_move ())
-+ done = 0, update_meta_data ();
-
-- if (const_cmp_to_sub ())
-- done = 0, update_meta_data ();
-+ if (const_cmp_to_sub ())
-+ done = 0, update_meta_data ();
-+
-+ if (merge_add ())
-+ done = 0, update_meta_data ();
-+
-+ if (elim_dead_assign ())
-+ done = 0, update_meta_data ();
-+ }
-
-- if (elim_dead_assign ())
-+ if (bb_reg_rename ())
- done = 0, update_meta_data ();
-
- if (done)
-@@ -1250,7 +1326,7 @@ namespace
- virtual bool
- gate (function *)
- {
-- return TARGET_AMIGA && flag_bbb_opts;
-+ return TARGET_AMIGA;// && flag_bbb_opts;
- }
-
- virtual unsigned int
-
-From 7ea53a15d0e3f77f38f9383d8779c7755c499e4b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 7 Apr 2017 04:07:36 +0200
-Subject: [PATCH 060/303] @B fix loop hang
-
----
- gcc/bbb-opts.c | 35 ++++++++++++++++-------------------
- 1 file changed, 16 insertions(+), 19 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index d9e77c53856d..c525ae432071 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1240,7 +1240,7 @@ merge_add (void)
- * Always prefer lower register numbers within the class.
- */
- static unsigned
--bb_reg_rename(void)
-+bb_reg_rename (void)
- {
- unsigned change_count = 0;
- for (unsigned index = 0; index < insns.size (); ++index)
-@@ -1262,29 +1262,26 @@ execute_bbb_optimizations (void)
- for (;;)
- {
- int done = 1;
-- for (;;)
-- {
-- if (propagate_moves ())
-- done = 0, update_meta_data ();
-+ if (propagate_moves ())
-+ done = 0, update_meta_data ();
-
-- if (offset_2_autoinc ())
-- done = 0, update_meta_data ();
-+ if (offset_2_autoinc ())
-+ done = 0, update_meta_data ();
-
-- if (opt_strcpy ())
-- done = 0, update_meta_data ();
-+ if (opt_strcpy ())
-+ done = 0, update_meta_data ();
-
-- if (commute_add_move ())
-- done = 0, update_meta_data ();
-+ if (commute_add_move ())
-+ done = 0, update_meta_data ();
-
-- if (const_cmp_to_sub ())
-- done = 0, update_meta_data ();
-+ if (const_cmp_to_sub ())
-+ done = 0, update_meta_data ();
-
-- if (merge_add ())
-- done = 0, update_meta_data ();
-+ if (merge_add ())
-+ done = 0, update_meta_data ();
-
-- if (elim_dead_assign ())
-- done = 0, update_meta_data ();
-- }
-+ if (elim_dead_assign ())
-+ done = 0, update_meta_data ();
-
- if (bb_reg_rename ())
- done = 0, update_meta_data ();
-@@ -1326,7 +1323,7 @@ namespace
- virtual bool
- gate (function *)
- {
-- return TARGET_AMIGA;// && flag_bbb_opts;
-+ return TARGET_AMIGA; // && flag_bbb_opts;
- }
-
- virtual unsigned int
-
-From cf6a128caf791e74460c8f312e624be2ab373b4e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 8 Apr 2017 17:06:18 +0200
-Subject: [PATCH 061/303] @N add option letters to -fbbb
-
----
- gcc/config/m68k/amigaos.opt | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 2d8bed0a9103..a5a14449dea9 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -43,6 +43,6 @@ mcrt=
- Target RejectNegative Var(amigaos_crt) Joined
- Specify startup binary
-
--fbbb
--Target Var(flag_bbb_opts,1) UInteger Init(0)
-+fbbb=
-+Target Var(flag_bbb_opts) Joined
- Enable Bebbo's optimizations
-
-From 477bce8c47781fce8d11797829a3bd6ade798273 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 8 Apr 2017 17:07:04 +0200
-Subject: [PATCH 062/303] @B some fixes, also invoke regrename directly, @R use
- letter from -fbbb=
-
----
- gcc/bbb-opts.c | 347 ++++++++++++++++++++++++++++++++++++++++----------------
- gcc/regrename.c | 12 +-
- 2 files changed, 260 insertions(+), 99 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index c525ae432071..737a5c00af3b 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -45,6 +45,7 @@
- #include "emit-rtl.h"
- #include "tree-pass.h"
- #include "conditions.h"
-+#include "cselib.h"
- #include <vector>
- #include <map>
-
-@@ -110,14 +111,14 @@ struct insn_info
- return t;
- }
-
-- inline insn_info
-- operator & (insn_info const & o) const
-- {
-- insn_info t;
-- t._use = _use & o._use;
-- t._def = _def & o._def;
-- return t;
-- }
-+// inline insn_info
-+// operator & (insn_info const & o) const
-+// {
-+// insn_info t;
-+// t._use = _use & o._use;
-+// t._def = _def & o._def;
-+// return t;
-+// }
-
- inline insn_info &
- operator |= (insn_info const & o)
-@@ -130,7 +131,7 @@ struct insn_info
- inline insn_info &
- operator &= (insn_info const & o)
- {
-- _use &= o._use;
-+ _use &= o._use & o._def;
- _def &= o._def;
- return *this;
- }
-@@ -162,6 +163,18 @@ struct insn_info
-
- void
- scan (rtx);
-+
-+ unsigned
-+ get_def_mask () const
-+ {
-+ if (!_def || _def > 0xffff)
-+ return 0;
-+
-+ unsigned mask = _def - 1;
-+ if (_def > 0xff)
-+ mask &= 0xff00;
-+ return mask;
-+ }
- };
-
- /* scan rtx for registers and set the corresponding flags. */
-@@ -192,6 +205,47 @@ insn_info::scan (rtx x)
- }
- }
-
-+/* perform reg renaming. */
-+static void
-+do_reg_rename (rtx x, unsigned oldregno, unsigned newregno)
++track_sp ()
+{
-+ if (REG_P(x))
++// reset visited flags - also check if sp is used as REG src.
++ for (unsigned index = 0; index < infos.size (); ++index)
+ {
-+ if (REGNO(x) == oldregno)
-+ df_ref_change_reg_with_loc (x, newregno);
-+ return;
-+ }
-+
-+ if (x == cc0_rtx)
-+ return;
++ insn_info & ii = infos[index];
++ ii.clear_visited ();
++ ii.set_sp_offset (0);
+
-+ RTX_CODE code = GET_CODE(x);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ do_reg_rename (XEXP(x, i), oldregno, newregno);
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ do_reg_rename (XVECEXP(x, i, j), oldregno, newregno);
++ // if sp is used as source, we cannot shrink the stack yet
++ // too complicated
++ if (ii.get_src_regno () == STACK_POINTER_REGNUM)
++ return -1;
+ }
-+}
+
-+static int
-+bit2regno (unsigned bit)
-+{
-+ if (!bit)
-+ return -1;
++// add entry point
++ std::set<unsigned> todo;
++ todo.insert (0);
+
-+ unsigned regno = 0;
-+ while (!(bit & 1))
++ while (todo.begin () != todo.end ())
+ {
-+ ++regno;
-+ bit >>= 1;
-+ }
-+ return regno;
-+}
-+
- /*
- * Collect some data.
- */
-@@ -212,22 +266,25 @@ clear (void)
- infos.clear ();
- }
-
-+/*
-+ * return true if the register is DEAD.
-+ */
- static bool
- is_reg_dead (unsigned regno, unsigned pos)
- {
-- if (pos >= infos.size ())
-- return true;
--
-- insn_info & ii0 = infos[pos++];
-- if (!ii0.is_use (regno))
-- return true;
--
-- if (pos >= infos.size ())
-- return true;
--
-- insn_info & ii1 = infos[pos];
-+ for(;;) {
-+ if (pos + 1 >= infos.size ())
-+ return true;
-+
-+ rtx_insn * insn = insns[pos + 1];
-+ if (!LABEL_P(insn) && GET_CODE(insn) != USE)
-+ break;
-+ ++pos;
-+ }
-
-- return !ii1.is_use (regno);
-+ insn_info & ii0 = infos[pos + 1];
-+ // not dead if usage is reported in the next statement
-+ return !ii0.is_use (regno);
- }
-
- /*
-@@ -242,6 +299,8 @@ dump_insns (char const * name)
- {
- insn_info & ii = infos[i];
-
-+ fprintf(stderr, "%d: ", i);
-+
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j))
- fprintf (stderr, ii.is_def (j) ? "*d%d " : "d%d ", j);
-@@ -301,6 +360,9 @@ update_meta_data ()
- std::pair<unsigned, insn_info> p = *todo.rbegin ();
- todo.pop_back ();
-
-+// fprintf(stderr, "%d ", p.first);
-+// dump_insns("update");
-+
- insn_info ii = p.second;
-
- for (int pos = p.first; pos >= 0; --pos)
-@@ -655,9 +717,8 @@ propagate_moves ()
- REGNO(srci), REGNO(dsti));
-
- /* Move in front of loop and mark as dead. */
-- remove_insn (ii);
-- add_insn_after (ii, before, 0);
-- add_reg_note (ii, REG_DEAD, srci);
-+ rtx_insn * newii = make_insn_raw(PATTERN(ii));
-+ SET_INSN_DELETED(ii);
-
- /* Plus check if the reg was just loaded. */
- if (bset)
-@@ -665,22 +726,31 @@ propagate_moves ()
- rtx bdst = SET_DEST(bset);
- if (REG_P(bdst) && REGNO(bdst) == REGNO(srci))
- {
-- SET_DEST(bset) = dsti;
-- SET_INSN_DELETED(ii);
-+ SET_SRC(PATTERN(newii)) = SET_SRC(bset);
-+// SET_INSN_DELETED(ii);
- }
- }
-+ else
-+ add_reg_note (newii, REG_DEAD, srci);
-+
-+
-+ add_insn_after (newii, before, 0);
-+
-
- /* Move behind loop - into next BB. */
-- remove_insn (jj);
-- add_insn_before (jj, after, 0);
-+ rtx_insn * newjj = make_insn_raw(PATTERN(jj));
-+ add_insn_before (newjj, after, 0);
-+ SET_INSN_DELETED(jj);
-
- reg_reg.erase (j);
- reg_reg.erase (i);
- j = reg_reg.end ();
- inc = false;
-
-- df_insn_rescan (ii);
-- df_insn_rescan (jj);
-+// df_insn_rescan (ii);
-+// df_insn_rescan (jj);
-+ df_insn_rescan (newii);
-+ df_insn_rescan (newjj);
-
- /* add fixes if there were jumps out of the loop. */
- if (jump_out.size ())
-@@ -761,17 +831,11 @@ opt_strcpy ()
- int num_clobbers_to_add = 0;
- int insn_code_number;
-
-- SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
-- insn_code_number = recog (PATTERN (reg2x), reg2x, &num_clobbers_to_add);
--
-- if (insn_code_number < 0 || !check_asm_operands (reg2x))
-+ rtx_insn * newinsn = make_insn_raw (
-+ gen_rtx_SET(SET_DEST(single_set(reg2x)), SET_SRC(single_set (x2reg))));
-+ insn_code_number = recog (PATTERN (newinsn), newinsn, &num_clobbers_to_add);
-+ if (insn_code_number >= 0 && check_asm_operands (PATTERN (newinsn)))
- {
-- /* restore register. */
-- SET_SRC(single_set(reg2x)) = SET_DEST(single_set (x2reg));
-- }
-- else
-- {
--
- rtx link;
-
- fprintf (
-@@ -779,6 +843,8 @@ opt_strcpy ()
- ":bbb: opt_strcpy condition met, removing compare and joining insns - omit reg %d\n",
- REGNO(dst));
-
-+ SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
-+
- for (link = REG_NOTES(x2reg); link; link = XEXP(link, 1))
- if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
- {
-@@ -935,16 +1001,20 @@ commute_add_move (void)
- rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1dst);
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
-+ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(reg1dst, reg1src));
-+ if (recog (PATTERN (newinsn), newinsn, 0) < 0 || !check_asm_operands (PATTERN (newinsn)))
-+ continue;
++ unsigned startpos = *todo.begin ();
++ todo.erase (todo.begin ());
+
- if (validate_change (next, &SET_DEST(set2), newmem, 0))
- {
-+ fprintf (stderr, ":bbb: commute_add_move found\n");
++ int sp_offset = infos[startpos].get_sp_offset ();
+
- SET_INSN_DELETED(insn);
-
-- insn = emit_insn_before (gen_movsi (reg1dst, reg1src), next);
-+ insn = emit_insn_before (newinsn, next);
-
- add_reg_note (next, REG_INC, reg1dst);
-
-- fprintf (stderr, ":bbb: commute_add_move found\n");
--
- df_insn_rescan (insn);
- df_insn_rescan (next);
-
-@@ -1037,18 +1107,11 @@ const_cmp_to_sub (void)
- rtx reg = dstp == left ? right : left;
- rtx plus = gen_rtx_PLUS(mode, reg, gen_rtx_CONST_INT (mode, intval));
-
-- SET_SRC(setp) = plus;
-- SET_DEST(setp) = reg;
-+ rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(reg, plus));
-
- int num_clobbers_to_add = 0;
-- int insn_code_number = recog (PATTERN (prev), prev, &num_clobbers_to_add);
-- if (insn_code_number >= 0 && !check_asm_operands (prev))
-- insn_code_number = -1;
--
-- SET_SRC(setp) = srcp;
-- SET_DEST(setp) = dstp;
--
-- if (insn_code_number < 0)
-+ int insn_code_number = recog (PATTERN (neuprev), neuprev, &num_clobbers_to_add);
-+ if (insn_code_number >= 0 && !check_asm_operands (PATTERN (neuprev)))
- continue;
-
- // also convert current statement to cmp #0, reg
-@@ -1058,11 +1121,11 @@ const_cmp_to_sub (void)
- add_reg_note (insn, REG_DEAD, reg);
-
- SET_INSN_DELETED(prev);
-- neu = gen_rtx_SET(reg, plus);
-- prev = emit_insn_before (neu, insn);
-+ prev = emit_insn_before (neuprev, insn);
-
- // urks - unknown side effects
- // int omitted_regno = REGNO(dstp);
-+// cselib_invalidate_rtx (dstp);
- // if (!(df->hard_regs_live_count[omitted_regno] -= 2))
- // df_set_regs_ever_live (omitted_regno, false);
-
-@@ -1159,7 +1222,7 @@ elim_dead_assign (void)
- if (!REG_P(dst) || !REG_P(src))
- continue;
-
-- if (!infos[index].is_use (REGNO(dst)))
-+ if (is_reg_dead(REGNO(dst),index))
- {
- fprintf (stderr, ":bbb: elim_dead_assign to %d\n", REGNO(dst));
- SET_INSN_DELETED(insn);
-@@ -1227,7 +1290,7 @@ merge_add (void)
- if (REGNO(dst1) != REGNO(dst2) || REGNO(r2) != REGNO(dst3))
- continue;
-
-- fprintf (stderr, ": merge_add pattern found\n");
-+ fprintf (stderr, ":bbb: merge_add applied\n");
-
- SET_SRC(set1) = l1;
- remove_insn (ins2);
-@@ -1242,60 +1305,82 @@ merge_add (void)
- static unsigned
- bb_reg_rename (void)
- {
-- unsigned change_count = 0;
-+ dump_insns("bb_reg_rename");
- for (unsigned index = 0; index < insns.size (); ++index)
- {
-- }
-- return change_count;
--}
-+ insn_info & ii = infos[index];
-+ const unsigned def = ii._def;
-+ unsigned mask = ii.get_def_mask ();
-
--/* Main entry point to the pass. */
--static unsigned int
--execute_bbb_optimizations (void)
--{
-- df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
-- df_note_add_problem ();
-- df_analyze ();
-+ if (!mask)
-+ continue;
-
-- update_meta_data ();
-+ std::vector<unsigned> found;
-+ std::vector<unsigned> todo;
-+ if (index + 1 < insns.size ())
-+ todo.push_back (index + 1);
-
-- for (;;)
-- {
-- int done = 1;
-- if (propagate_moves ())
-- done = 0, update_meta_data ();
-+ found.push_back (index);
-+ /* a register was defined, follow all branches. */
-+ while (todo.size ())
++ for (unsigned index = startpos; index < infos.size (); ++index)
+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
-
-- if (offset_2_autoinc ())
-- done = 0, update_meta_data ();
-+ insn_info & jj = infos[pos];
-+ /* defined again. */
-+ if (jj._def & def)
-+ continue;
-
-- if (opt_strcpy ())
-- done = 0, update_meta_data ();
-+ /* not referenced. */
-+ if (!(jj._use & def))
-+ continue;
-
-- if (commute_add_move ())
-- done = 0, update_meta_data ();
-+ /* update free regs. */
-+ mask &= ~jj._use;
-+ if (!mask)
-+ break;
-
-- if (const_cmp_to_sub ())
-- done = 0, update_meta_data ();
-+ found.push_back (pos);
-
-- if (merge_add ())
-- done = 0, update_meta_data ();
-+ /* follow jump and/or next insn. */
-+ rtx_insn * insn = insns[index];
-+ if (JUMP_P(insn))
++ insn_info & ii = infos[index];
++ if (ii.in_proepi () != IN_CODE)
+ {
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-+ if (j != insn2index.end ())
-+ todo.push_back (j->second);
-
-- if (elim_dead_assign ())
-- done = 0, update_meta_data ();
-+ rtx jmppattern = PATTERN (insn);
-
-- if (bb_reg_rename ())
-- done = 0, update_meta_data ();
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-+ if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
++ ii.set_sp_offset (sp_offset);
++ continue;
+ }
-+ else if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
-+ }
-
-- if (done)
-- break;
-- }
-+ if (mask)
-+ {
-+ int oldregno = bit2regno (def);
-+ int newregno = bit2regno (mask);
-+ fprintf (stderr, ":bbb: bb_reg_rename %d -> %d\n", oldregno, newregno);
-
--// dump_insns ("bbb 1");
-- clear ();
-+ for (std::vector<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
-+ do_reg_rename (PATTERN (insns[*i]), oldregno, newregno);
-
-+ cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
-+ cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
-+ return 1;
-+ }
-+ }
- return 0;
- }
-
-+extern class opt_pass * global_pass_regrename;
-+
- namespace
- {
-
-@@ -1315,7 +1400,7 @@ namespace
- {
- public:
- pass_bbb_optimizations (gcc::context *ctxt) :
-- rtl_opt_pass (pass_data_bbb_optimizations, ctxt)
-+ rtl_opt_pass (pass_data_bbb_optimizations, ctxt), pp (0)
- {
- }
-
-@@ -1323,7 +1408,7 @@ namespace
- virtual bool
- gate (function *)
- {
-- return TARGET_AMIGA; // && flag_bbb_opts;
-+ return TARGET_AMIGA && flag_bbb_opts;
- }
-
- virtual unsigned int
-@@ -1335,13 +1420,81 @@ namespace
- opt_pass *
- clone ()
- {
-- return new pass_bbb_optimizations (m_ctxt);
-+ pass_bbb_optimizations * bbb = new pass_bbb_optimizations (m_ctxt);
-+ // bbb->pp = pp + 1;
-+ return bbb;
- }
-
-+ unsigned int pp;
-+
-+ unsigned
-+ execute_bbb_optimizations (void);
- };
- // class pass_bbb_optimizations
-
--}// anon namespace
-+
-+ /* Main entry point to the pass. */
-+ unsigned
-+ pass_bbb_optimizations::execute_bbb_optimizations (void)
-+ {
-+ df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
-+ df_note_add_problem ();
-+ df_analyze ();
-+
-+ update_meta_data ();
-+
-+ bool do_opt_strcpy = strchr(flag_bbb_opts, 's') || strchr(flag_bbb_opts, '*');
-+ bool do_commute_add_move = strchr(flag_bbb_opts, 'a') || strchr(flag_bbb_opts, '*');
-+ bool do_propagate_moves = strchr(flag_bbb_opts, 'p') || strchr(flag_bbb_opts, '*');
-+ bool do_const_cmp_to_sub = strchr(flag_bbb_opts, 'c') || strchr(flag_bbb_opts, '*');
-+ bool do_merge_add = strchr(flag_bbb_opts, 'm') || strchr(flag_bbb_opts, '*');
-+ bool do_elim_dead_assign = strchr(flag_bbb_opts, 'e') || strchr(flag_bbb_opts, '*');
-+ bool do_bb_reg_rename = strchr(flag_bbb_opts, 'r') || strchr(flag_bbb_opts, '*');
+
++ // already visited? sp_offset must match
++ if (ii.is_visited ())
++ {
++ if (ii.get_sp_offset () != sp_offset)
++ return E_SP_MISMATCH;
++ break;
++ }
+
-+ for (;;)
-+ {
-+ int done = 1;
-+ if (do_opt_strcpy && opt_strcpy ())
-+ done = 0, update_meta_data ();
-+
-+ if (do_commute_add_move && commute_add_move ())
-+ done = 0, update_meta_data ();
-+
-+ if (do_propagate_moves && propagate_moves ())
-+ done = 0, update_meta_data ();
-+
-+// if (offset_2_autoinc ())
-+// done = 0, update_meta_data ();
-+
-+ if (do_const_cmp_to_sub && const_cmp_to_sub ())
-+ done = 0, update_meta_data ();
-+
-+ if (do_merge_add && merge_add ())
-+ done = 0, update_meta_data ();
-+
-+ if (do_elim_dead_assign && elim_dead_assign ())
-+ done = 0, update_meta_data ();
++ // mark current insn_info and set sp_offset
++ ii.mark_visited ();
++ ii.set_sp_offset (sp_offset);
+
-+// if (do_bb_reg_rename && bb_reg_rename ())
-+// done = 0, update_meta_data ();
-+ if (done)
-+ break;
-+ }
++ // add all referred labels
++ if (ii.is_jump ())
++ {
++ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i)
++ {
++ insn_info & ll = infos[i->second];
++ if (ll.is_visited () && ll.get_sp_offset () != sp_offset)
++ return E_SP_MISMATCH;
+
-+ if (do_bb_reg_rename && ::global_pass_regrename)
-+ {
-+ class opt_pass * rr = ::global_pass_regrename->clone();
-+ rr->execute(0);
-+ }
++ ll.set_sp_offset (sp_offset);
++ todo.insert (i->second);
++ }
++ continue;
++ }
+
-+ if (strchr(flag_bbb_opts, 'X')) dump_insns ("bbb 1");
-+ clear ();
++ // is sp modified directly
++ if (ii.is_dst_reg () && ii.get_dst_regno () == STACK_POINTER_REGNUM)
++ {
++ // handle sp = sp + const_int
++ if (!ii.get_src_reg () || ii.get_src_regno () != STACK_POINTER_REGNUM || ii.get_src_op () != PLUS)
++ return E_SP_MISMATCH;
+
-+ return 0;
-+ }
++ sp_offset = sp_offset + ii.get_src_intval ();
++ continue;
++ }
+
-+} // anon namespace
-
- rtl_opt_pass *
- make_pass_bbb_optimizations (gcc::context * ctxt)
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index 4ba825e8d8e8..696e5557780e 100755
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -1913,6 +1913,8 @@ regrename_optimize (void)
- return 0;
- }
-
-+class opt_pass * global_pass_regrename;
++ // handle dst mem autoinc
++ if (ii.is_dst_mem () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM && ii.get_dst_autoinc ())
++ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_dst_autoinc ();
+
- namespace {
-
- const pass_data pass_data_regrename =
-@@ -1927,13 +1929,14 @@ const pass_data pass_data_regrename =
- 0, /* todo_flags_start */
- TODO_df_finish, /* todo_flags_finish */
- };
--
- class pass_regrename : public rtl_opt_pass
- {
- public:
- pass_regrename (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_regrename, ctxt)
-- {}
-+ {
-+ ::global_pass_regrename = this;
-+ }
-
- /* opt_pass methods: */
- virtual bool gate (function *)
-@@ -1943,6 +1946,11 @@ class pass_regrename : public rtl_opt_pass
-
- virtual unsigned int execute (function *) { return regrename_optimize (); }
-
-+ opt_pass * clone ()
-+ {
-+ return new pass_regrename(m_ctxt);
++ // handle src mem autoinc
++ if (ii.is_src_mem () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM && ii.get_src_autoinc ())
++ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_src_autoinc ();
++ }
+ }
+
- }; // class pass_regrename
-
- } // anon namespace
-
-From b747a5666a06f73ae8628788246f6d9e614f6393 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 10 Apr 2017 10:46:07 +0200
-Subject: [PATCH 063/303] @B shrink_stack_frame starts working
-
----
- gcc/bbb-opts.c | 583 ++++++++++++++++++++++++++++++++++++++++++---------------
- gcc/passes.def | 1 -
- 2 files changed, 427 insertions(+), 157 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 737a5c00af3b..6114e2fa5ed0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -111,15 +111,6 @@ struct insn_info
- return t;
- }
-
--// inline insn_info
--// operator & (insn_info const & o) const
--// {
--// insn_info t;
--// t._use = _use & o._use;
--// t._def = _def & o._def;
--// return t;
--// }
--
- inline insn_info &
- operator |= (insn_info const & o)
- {
-@@ -250,6 +241,7 @@ bit2regno (unsigned bit)
- * Collect some data.
- */
- static std::vector<rtx_insn *> insns;
-+static std::vector<rtx_insn *> temp;
- static std::vector<rtx_insn *> jumps;
- static std::map<rtx_insn *, unsigned> insn2index;
- static std::vector<insn_info> infos;
-@@ -272,15 +264,16 @@ clear (void)
- static bool
- is_reg_dead (unsigned regno, unsigned pos)
- {
-- for(;;) {
-- if (pos + 1 >= infos.size ())
-- return true;
--
-- rtx_insn * insn = insns[pos + 1];
-- if (!LABEL_P(insn) && GET_CODE(insn) != USE)
-- break;
-- ++pos;
-- }
-+ for (;;)
-+ {
-+ if (pos + 1 >= infos.size ())
-+ return true;
++ return 0;
++}
+
-+ rtx_insn * insn = insns[pos + 1];
-+ if (!LABEL_P(insn) && GET_CODE(insn) != USE)
-+ break;
-+ ++pos;
-+ }
-
- insn_info & ii0 = infos[pos + 1];
- // not dead if usage is reported in the next statement
-@@ -292,14 +285,19 @@ is_reg_dead (unsigned regno, unsigned pos)
- * Sometimes used during debugging.
- */
- static void
--dump_insns (char const * name)
-+dump_insns (char const * name, bool all)
- {
- fprintf (stderr, "====================================: %s\n", name);
-+ if (all)
++/* recursive function to patch stack pointer offsets. */
++void
++patch_sp (rtx x, int adjust, int spoffset)
++{
++ int code = GET_CODE(x);
++ if (code == PLUS)
+ {
-+ for (rtx_insn * insn = get_insns (); insn && insn != insns[0]; insn = NEXT_INSN (insn))
-+ debug_rtx (insn);
-+ }
- for (unsigned i = 0; i < insns.size (); ++i)
- {
- insn_info & ii = infos[i];
-
-- fprintf(stderr, "%d: ", i);
-+ fprintf (stderr, "%d: ", i);
-
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j))
-@@ -314,6 +312,13 @@ dump_insns (char const * name)
-
- fprintf (stderr, "\t");
- debug_rtx (insns[i]);
-+
-+ if (all)
++ rtx a = XEXP(x, 0);
++ rtx b = XEXP(x, 1);
++ if (REG_P(a) && REGNO(a) == STACK_POINTER_REGNUM && GET_CODE(b) == CONST_INT)
+ {
-+ rtx_insn * p = i + 1 < insns.size () ? insns[i + 1] : 0;
-+ for (rtx_insn * q = NEXT_INSN (insns[i]); q && q != p; q = NEXT_INSN (q))
-+ debug_rtx (q);
++ if (INTVAL(b) > -spoffset)
++ XEXP(x, 1) = gen_rtx_CONST_INT (GET_MODE(b), INTVAL(b) - adjust);
++ return;
+ }
- }
- }
-
-@@ -321,7 +326,7 @@ dump_insns (char const * name)
- * Create a filtered view of insns - keep only those to work with.
- */
- static void
--update_meta_data ()
-+update_insns ()
- {
- rtx_insn *insn, *next;
- clear ();
-@@ -342,7 +347,11 @@ update_meta_data ()
- insns.push_back (insn);
- }
- }
-+}
-
-+static void
-+update_insn_infos (void)
-+{
- /* prepare insn_info */
- insn_info ii;
- for (unsigned i = 0; i < insns.size (); ++i)
-@@ -360,14 +369,13 @@ update_meta_data ()
- std::pair<unsigned, insn_info> p = *todo.rbegin ();
- todo.pop_back ();
-
--// fprintf(stderr, "%d ", p.first);
--// dump_insns("update");
--
- insn_info ii = p.second;
-
- for (int pos = p.first; pos >= 0; --pos)
- {
- rtx_insn * insn = insns[pos];
-+ if (!insn) // moved to temp for stack frame cleanup
-+ continue;
-
- if (pass && infos[pos].contains (ii))
- break;
-@@ -487,7 +495,6 @@ update_meta_data ()
- }
- ++pass;
- }
--
- }
-
- /*
-@@ -717,7 +724,7 @@ propagate_moves ()
- REGNO(srci), REGNO(dsti));
-
- /* Move in front of loop and mark as dead. */
-- rtx_insn * newii = make_insn_raw(PATTERN(ii));
-+ rtx_insn * newii = make_insn_raw (PATTERN (ii));
- SET_INSN_DELETED(ii);
-
- /* Plus check if the reg was just loaded. */
-@@ -733,12 +740,10 @@ propagate_moves ()
- else
- add_reg_note (newii, REG_DEAD, srci);
-
--
- add_insn_after (newii, before, 0);
-
--
- /* Move behind loop - into next BB. */
-- rtx_insn * newjj = make_insn_raw(PATTERN(jj));
-+ rtx_insn * newjj = make_insn_raw (PATTERN (jj));
- add_insn_before (newjj, after, 0);
- SET_INSN_DELETED(jj);
-
-@@ -895,47 +900,6 @@ opt_strcpy ()
- return change_count;
- }
-
--/*
-- * Convert loops using a counting reg as offset with an address reg
-- * into a loop with auto inc address regs.
-- */
--static unsigned
--offset_2_autoinc (void)
--{
-- unsigned change_count = 0;
--#if 0
-- rtx_insn * reg_const = 0;
--
-- for (unsigned index = 0; index < insns.size (); ++index)
-- {
-- rtx_insn * insn = insns[index];
--
-- if (!next || !LABEL_P(next) || LABEL_NUSES(next) != 1)
-- continue;
--
-- if (!NONJUMP_INSN_P(insn))
-- continue;
--
-- rtx use = single_set (insn);
-- if (!use)
-- continue;
--
-- rtx reg = SET_DEST(use);
-- if (!REG_P(reg))
-- continue;
--
-- rtx val = SET_SRC(use);
--
--// fprintf(stderr, "possible start for offset_2_autoinc\n");
--// //debug_rtx(insn);
--// //debug_rtx(next);
--
-- }
--
--#endif
-- return change_count;
--}
--
- /*
- * convert
- *
-@@ -1052,7 +1016,7 @@ const_cmp_to_sub (void)
- {
- unsigned change_count = 0;
- #if HAVE_cc0
-- for (unsigned index = 1; index + 1 < insns.size (); ++index)
-+ for (unsigned index = insns.size () - 2; index > 0; --index)
- {
- rtx_insn * insn = insns[index];
- rtx seti = single_set (insn);
-@@ -1072,13 +1036,13 @@ const_cmp_to_sub (void)
- if (!REG_P(left) || !REG_P(right))
- continue;
-
--// if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
--// continue;
--
- // TODO
- // FEATURE: check if the next uses are also a add/sub
- // then maybe that add/sub can be adjusted too
-
-+ // if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
-+ // continue;
-+ // use own reg_dead
- if (!is_reg_dead (REGNO(left), index) || !is_reg_dead (REGNO(right), index))
- continue;
-
-@@ -1222,7 +1186,7 @@ elim_dead_assign (void)
- if (!REG_P(dst) || !REG_P(src))
- continue;
-
-- if (is_reg_dead(REGNO(dst),index))
-+ if (is_reg_dead (REGNO(dst), index))
- {
- fprintf (stderr, ":bbb: elim_dead_assign to %d\n", REGNO(dst));
- SET_INSN_DELETED(insn);
-@@ -1278,8 +1242,8 @@ merge_add (void)
- continue;
-
- rtx l1 = XEXP(src1, 0);
-- rtx l2 = XEXP(src2, 0);
-- rtx l3 = XEXP(src3, 0);
-+// rtx l2 = XEXP(src2, 0);
-+// rtx l3 = XEXP(src3, 0);
-
- rtx r1 = XEXP(src1, 1);
- rtx r2 = XEXP(src2, 1);
-@@ -1293,89 +1257,393 @@ merge_add (void)
- fprintf (stderr, ":bbb: merge_add applied\n");
-
- SET_SRC(set1) = l1;
-- remove_insn (ins2);
-- add_insn_after (ins2, ins3, 0);
-+ rtx_insn * newins2 = make_insn_raw (PATTERN (ins2));
-+ add_insn_after (newins2, ins3, 0);
-+ SET_INSN_DELETED(ins2);
-+ df_insn_rescan (ins1);
- }
- return change_count;
- }
-
--/*
-- * Always prefer lower register numbers within the class.
-+static void
-+clear_temp ()
-+{
-+ for (unsigned i = 0; i < temp.size (); ++i)
-+ if (temp[i])
-+ insns[i] = temp[i], temp[i] = 0;
++ }
++ const char *fmt = GET_RTX_FORMAT(code);
++ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
++ {
++ if (fmt[i] == 'e')
++ patch_sp (XEXP(x, i), adjust, spoffset);
++ else if (fmt[i] == 'E')
++ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
++ patch_sp (XVECEXP(x, i, j), adjust, spoffset);
++ }
+}
+
+/**
@@ -11490,45 +4159,40 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ *
+ * startvalue count(pushes)*4
+ * newstartvalue = startvalue - omitted pushes
- */
- static unsigned
--bb_reg_rename (void)
-+shrink_stack_frame (void)
- {
-- dump_insns("bb_reg_rename");
-- for (unsigned index = 0; index < insns.size (); ++index)
++ */
++static unsigned
++opt_shrink_stack_frame (void)
++{
+ /* nothing to do. */
-+ if (!insns.size ())
++ if (!infos.size ())
+ return 0;
+
-+ temp.resize (insns.size ());
++ /* needed to track sp correctly. */
++ update_label2jump ();
++ if (track_sp ())
++ return 0; // do nothing on stack errors
++
++ std::vector<int> a5pos;
+
+ unsigned pos = 0;
-+ rtx_insn * insn = insns[pos];
++ rtx_insn * insn = infos[pos].get_insn ();
+ if (JUMP_P(insn)) /* return -> empty function*/
+ return 0;
+
+ bool usea5 = false;
-+ unsigned paramstart = 4;
++ int paramstart = 4;
++ int a5offset = 0;
++
+ /*
+ * Move prologue to temp.
+ * Only register push and parallel insn unless its a link a5 are moved.
+ */
-+ rtx_insn * prev = get_insns ();
-+ for (; pos < insns.size ();)
- {
-- insn_info & ii = infos[index];
-- const unsigned def = ii._def;
-- unsigned mask = ii.get_def_mask ();
-+ insn = insns[pos];
-
-- if (!mask)
-- continue;
-+ /* check for prologue end. */
-+ for (; prev != insn; prev = NEXT_INSN (prev))
-+ if (NOTE_P(prev) && NOTE_KIND(prev) == NOTE_INSN_PROLOGUE_END)
-+ break;
-+ if (prev != insn)
++ for (; pos < infos.size ();)
++ {
++ insn_info & ii = infos[pos];
++ insn = ii.get_insn ();
++
++ if (ii.in_proepi () != IN_PROLOGUE)
+ break;
+
+ rtx pattern = PATTERN (insn);
@@ -11536,20 +4200,23 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ {
+ rtx set = XVECEXP(pattern, 0, 0);
+ rtx dst = SET_DEST(set);
++ ii.mark_stack ();
+ /* ignore link a5 */
-+ if (REG_P(dst) && REGNO(dst) == 13)
-+ usea5 = true;
-+ else
++ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
+ {
-+ /* use movem */
-+ temp[pos] = insn;
-+ insns[pos] = 0;
++ a5pos.push_back (pos);
++ usea5 = true;
++ set = XVECEXP(pattern, 0, 2);
++ a5offset = INTVAL(XEXP(SET_SRC(set), 1));
+ }
+ ++pos;
+ continue;
+ }
+ if (GET_CODE(pattern) != SET)
+ {
++ /* (set (mem:BLK (scratch) [0 A8]) (unspec:BLK [ ...)) */
++ if (MEM_P(SET_DEST(pattern)) && GET_CODE(SET_SRC(pattern)) == UNSPEC)
++ a5pos.push_back (pos);
+ ++pos;
+ continue;
+ }
@@ -11565,100 +4232,65 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ if (GET_CODE(predec) == PRE_DEC)
+ {
+ rtx reg = XEXP(predec, 0);
-+ if (REG_P(reg) && REGNO(reg) == 15)
++ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
+ {
-+ temp[pos] = insn;
-+ insns[pos] = 0;
++ ii.mark_stack ();
+ }
+ }
+ }
+ }
-+ else if (GET_CODE(src) == PLUS && REG_P(dest) && REGNO(dest) == 15)
++ else if (GET_CODE(src) == PLUS && REG_P(dest) && REGNO(dest) == STACK_POINTER_REGNUM)
+ {
+ /* check for stack variables. */
+ rtx reg = XEXP(src, 0);
+ rtx cx = XEXP(src, 1);
-+ if (REG_P(reg) && REGNO(reg) == 15 && CONST_INT_P(cx))
++ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM && CONST_INT_P(cx))
+ paramstart -= INTVAL(cx);
+ }
+
-+ if (++pos >= insns.size ())
++ if (++pos >= infos.size ())
+ {
-+ clear_temp ();
+ return 0;
+ }
+ }
-
-- std::vector<unsigned> found;
-- std::vector<unsigned> todo;
-- if (index + 1 < insns.size ())
-- todo.push_back (index + 1);
++
+ if (pos == 0)
+ return 0;
+
+ unsigned prologueend = pos;
-
-- found.push_back (index);
-- /* a register was defined, follow all branches. */
-- while (todo.size ())
++
+ /* search epilogues - there can be multiple epilogues. */
-+ while (pos < insns.size ())
++ while (pos < infos.size ())
+ {
-+ while (pos < insns.size ())
- {
-- unsigned pos = todo[todo.size () - 1];
-- todo.pop_back ();
-+ insn = insns[pos];
-+ for (; prev != insn; prev = NEXT_INSN (prev))
-+ if (NOTE_P(prev) && NOTE_KIND(prev) == NOTE_INSN_EPILOGUE_BEG)
-+ break;
-
-- insn_info & jj = infos[pos];
-- /* defined again. */
-- if (jj._def & def)
-- continue;
-+ if (prev != insn)
++ while (pos < infos.size ())
++ {
++ if (infos[pos].in_proepi () != IN_CODE)
+ break;
-
-- /* not referenced. */
-- if (!(jj._use & def))
-- continue;
+ ++pos;
+ }
-
-- /* update free regs. */
-- mask &= ~jj._use;
-- if (!mask)
++
+ /* move epilogues away. */
-+ for (; pos < insns.size (); ++pos)
++ for (; pos < infos.size (); ++pos)
+ {
-+ insn = insns[pos];
-+ if (JUMP_P(insn)) /* return */
- break;
-
-- found.push_back (pos);
-+ if (LABEL_P(insn))
++ insn_info & ii = infos[pos];
++ insn = ii.get_insn ();
++ if (JUMP_P(insn) || LABEL_P(insn) || ii.in_proepi () == IN_CODE)
+ break;
-
-- /* follow jump and/or next insn. */
-- rtx_insn * insn = insns[index];
-- if (JUMP_P(insn))
-+ /* omitt the frame pointer a5. */
++
++ /* omit the frame pointer a5. */
+ rtx pattern = PATTERN (insn);
+ if (GET_CODE(pattern) == PARALLEL)
- {
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-- if (j != insn2index.end ())
-- todo.push_back (j->second);
++ {
+ rtx set = XVECEXP(pattern, 0, 0);
+ rtx dst = SET_DEST(set);
++ ii.mark_stack ();
+ /* unlink is last. */
-+ if (REG_P(dst) && REGNO(dst) == 13)
-+ break;
++ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
++ {
++ a5pos.push_back (pos);
++ break;
++ }
+
-+ /* movem. */
-+ temp[pos] = insn;
-+ insns[pos] = 0;
+ }
+ else if (GET_CODE(pattern) == SET)
+ {
@@ -11673,11 +4305,14 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ if (GET_CODE(postinc) == POST_INC)
+ {
+ rtx reg = XEXP(postinc, 0);
-+ if (REG_P(reg) && REGNO(reg) == 15)
-+ {
-+ temp[pos] = insn;
-+ insns[pos] = 0;
-+ }
++ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
++ ii.mark_stack ();
++ }
++ else if (GET_CODE(postinc) == PLUS)
++ {
++ rtx a5 = XEXP(postinc, 0);
++ if (REG_P(a5) && REGNO(a5) == FRAME_POINTER_REGNUM)
++ ii.mark_stack ();
+ }
+ }
+ }
@@ -11686,31 +4321,47 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ ++pos;
+ }
+ /* gather usage stats without prologue/epilogue */
-+ update_insn_infos ();
+ insn_info ii;
+ for (unsigned i = 0; i < infos.size (); ++i)
-+ ii |= infos[i];
-+ unsigned freemask = ~ii._use;
-
-- rtx jmppattern = PATTERN (insn);
-+ rtx a7 = gen_raw_REG (SImode, 15);
-
-- rtx jmpsrc = XEXP(jmppattern, 1);
-- if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-- if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
++ {
++ insn_info & jj = infos[i];
++ if (jj.in_proepi () != IN_CODE)
++ continue;
++
++ ii.or_use (jj);
++ }
++ unsigned freemask = ~ii.get_use () & 0x7fff;
++
++ rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
++ rtx a5 = gen_raw_REG (SImode, FRAME_POINTER_REGNUM);
++
++ unsigned changed = 0;
+ unsigned adjust = 0;
++ unsigned regs_seen = 0;
++ unsigned regs_total_size = 0;
+ /* now all push/pop insns are in temp. */
-+ for (unsigned i = 0; i < temp.size (); ++i)
++ for (unsigned i = 0; i < infos.size (); ++i)
+ {
-+ insn = temp[i];
-+ if (!insn)
++ insn_info & ii = infos[i];
++ if (!ii.is_stack ())
+ continue;
+
++ insn = ii.get_insn ();
+ rtx pattern = PATTERN (insn);
+ /* check the pushed regs, either a vector or single statements */
+ if (GET_CODE(pattern) == PARALLEL)
+ {
++ // do not touch the frame pointer parallel insn.
++ rtx set = XVECEXP(pattern, 0, 0);
++ rtx dst = SET_DEST(set);
++ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
++ continue;
++
++ if (ii.in_proepi () == IN_EPILOGUE)
++ ii.set_proepi (IN_EPILOGUE_PARALLEL_POP);
++
++ regs_seen = 0;
++ regs_total_size = 0;
+ std::vector<rtx> regs;
+ std::vector<rtx> clobbers;
+ for (int j = 0; j < XVECLEN(pattern, 0); ++j)
@@ -11721,8 +4372,8 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ clobbers.push_back (set);
+ continue;
+ }
-+ rtx src = SET_SRC(set);
+ rtx dst = SET_DEST(set);
++ rtx src = SET_SRC(set);
+ rtx reg;
+ if (MEM_P(src))
+ reg = dst;
@@ -11734,40 +4385,50 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ if (i < prologueend)
+ paramstart += 4;
+ unsigned regbit = 1 << REGNO(reg);
++
++ ++regs_seen;
+ if (freemask & regbit)
+ {
-+ fprintf (stderr, i < prologueend ? "remove push for %d\n" : "remove pop for %d\n", REGNO(reg));
++ log (i < prologueend ? "(f) remove push for %s\n" : "(f) remove pop for %s\n",
++ reg_names[REGNO(reg)]);
+ if (i < prologueend)
-+ adjust += 4;
++ adjust += GET_MODE_SIZE(GET_MODE(reg));
+ }
+ else
-+ regs.push_back (reg);
++ {
++ regs_total_size += GET_MODE_SIZE(GET_MODE(reg));
++ regs.push_back (copy_reg (reg, -1));
++ }
+ }
+
-+ /* don't touch - clobbers! */
-+ if (clobbers.size())
-+ continue;
-+
-+ if ((int) regs.size () + 1 < XVECLEN(pattern, 0) || regs.size () <= 2)
++ /* add room for add.
++ * push is always using -(a7) addressing.
++ * If a5 is used a movem offset(a5) is generated to pop saved registers..
++ * Otherwise a7 is used and with (a7)+ addressing.
++ */
++ int add1 = i < prologueend || !usea5 ? 1 : 0;
++ if (regs.size () < regs_seen)
+ {
++ log ("(f) shrinking stack frame from %d to %d\n", regs_seen, regs.size ());
+ if (regs.size () <= 2)
+ {
++ changed = 1;
+ for (unsigned k = 0; k < regs.size (); ++k)
+ {
+ rtx reg = regs[k];
+ if (i < prologueend)
+ {
+ /* push */
-+ rtx dec = gen_rtx_PRE_DEC(SImode, a7);
-+ rtx mem = gen_rtx_MEM (SImode, dec);
++ rtx dec = gen_rtx_PRE_DEC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
++ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
+ rtx set = gen_rtx_SET(mem, reg);
+ emit_insn_after (set, insn);
+ }
+ else
+ {
+ /* pop */
-+ rtx dec = gen_rtx_POST_INC(SImode, a7);
-+ rtx mem = gen_rtx_MEM (SImode, dec);
++ rtx dec = gen_rtx_POST_INC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
++ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
+ rtx set = gen_rtx_SET(reg, mem);
+ emit_insn_before (set, insn);
+ }
@@ -11775,39 +4436,73 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ }
+ else
+ {
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + 1));
-+ int x = regs.size () * 4 + 4;
++ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1 + clobbers.size ()));
++ rtx plus;
+
-+ rtx plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-+ XVECEXP(parallel, 0, 0) = gen_rtx_SET(a7, plus);
++ int x = 0;
++ for (unsigned k = 0; k < regs.size (); ++k)
++ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
++
++ unsigned l = 0;
++ /* no add if a5 is used with pop */
++ if (add1)
++ {
++ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
++ XVECEXP(parallel, 0, l) = gen_rtx_SET(a7, plus);
++ ++l;
++ }
+
+ if (i >= prologueend)
-+ x = 0;
++ x = usea5 ? -x : 0;
+
-+ for (unsigned k = 0; k < regs.size (); ++k)
++ for (unsigned k = 0; k < regs.size (); ++k, ++l)
+ {
+ if (i < prologueend)
+ {
+ /* push */
+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, -x));
-+ x -= 4;
-+ rtx mem = gen_rtx_MEM (SImode, plus);
++ x -= REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
++ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
+ rtx set = gen_rtx_SET(mem, regs[k]);
-+ XVECEXP(parallel, 0, k + 1) = set;
++ XVECEXP(parallel, 0, l) = set;
+ }
+ else
+ {
+ /* pop */
-+ plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
-+ x += 4;
-+ rtx mem = gen_rtx_MEM (SImode, plus);
-+ rtx set = gen_rtx_SET(regs[k], mem);
-+ XVECEXP(parallel, 0, k + 1) = set;
++ if (usea5)
++ {
++ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
++ plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
++ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
++ rtx set = gen_rtx_SET(regs[k], mem);
++ XVECEXP(parallel, 0, l) = set;
++ }
++ else
++ {
++ plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
++ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
++ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
++ rtx set = gen_rtx_SET(regs[k], mem);
++ XVECEXP(parallel, 0, l) = set;
++ }
+ }
+ }
-+ emit_insn_after (parallel, insn);
++
++ for (unsigned k = 0; k < clobbers.size (); ++k, ++l)
++ {
++ rtx clobber = clobbers[k];
++ XVECEXP(parallel, 0, l) = clobber;
++ }
++
++ rtx_insn * neu;
++ if (i < prologueend)
++ neu = emit_insn_after (parallel, insn);
++ else
++ neu = emit_insn_before (parallel, insn);
++ ii.set_insn (neu);
+ }
+ SET_INSN_DELETED(insn);
++ changed = 1;
+ }
+ }
+ else
@@ -11817,14 +4512,15 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ if (i < prologueend)
+ {
+ /* move x,-(a7). */
-+ paramstart += 4;
+ rtx src = SET_SRC(set);
++ paramstart += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
+ unsigned regbit = 1 << REGNO(src);
+ if (freemask & regbit)
+ {
-+ adjust += 4;
-+ fprintf (stderr, "remove push for %d\n", REGNO(src));
++ adjust += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
++ log ("(f) remove push for %s\n", reg_names[REGNO(src)]);
+ SET_INSN_DELETED(insn);
++ ++changed;
+ }
+ }
+ else
@@ -11834,2822 +4530,1365 @@ index 737a5c00af3b..6114e2fa5ed0 100755
+ unsigned regbit = 1 << REGNO(dst);
+ if (freemask & regbit)
+ {
-+ fprintf (stderr, "remove pop for %d\n", REGNO(dst));
++ log ("(f) remove pop for %s\n", reg_names[REGNO(dst)]);
+ SET_INSN_DELETED(insn);
++ ++changed;
+ }
- }
-- else if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
- }
++ }
++ }
+ }
-
-- if (mask)
++
+ /* fix sp offsets. */
+ if (!usea5 && adjust)
+ {
-+ for (unsigned index = 0; index < insns.size (); ++index)
- {
-- int oldregno = bit2regno (def);
-- int newregno = bit2regno (mask);
-- fprintf (stderr, ":bbb: bb_reg_rename %d -> %d\n", oldregno, newregno);
-+ insn = insns[index];
-+ if (!insn || !INSN_P(insn))
-+ continue;
-
-- for (std::vector<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
-- do_reg_rename (PATTERN (insns[*i]), oldregno, newregno);
-+ rtx set = single_set (insn);
-+ if (!set)
++ for (unsigned index = 0; index < infos.size (); ++index)
++ {
++ insn_info & ii = infos[index];
++ if (ii.in_proepi () != IN_CODE)
+ continue;
-
-- cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
-- cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
-- return 1;
-+ rtx mem = SET_SRC(set);
-+ if (MEM_P(mem))
++
++ rtx pattern = single_set (ii.get_insn ());
++ if (pattern)
++ patch_sp (pattern, adjust, ii.get_sp_offset ());
++ }
++ }
++
++ if (usea5 && a5offset == -4)
++ {
++ /* for now only drop the frame pointer if it's not used.
++ * Needs tracking of the sp to adjust the offsets.
++ */
++ if (freemask & (1 << FRAME_POINTER_REGNUM))
++ {
++ log ("(f) dropping unused frame pointer\n");
++ for (std::vector<int>::reverse_iterator i = a5pos.rbegin (); i != a5pos.rend (); ++i)
++ {
++ int index = *i;
++ SET_INSN_DELETED(infos[index].get_insn ());
++
++ // move to last insn in epilogue
++ while (index - 1 > 0 && infos[index - 1].in_proepi () >= IN_EPILOGUE)
++ --index;
++
++ insn_info & ii = infos[index];
++ if (ii.in_proepi () >= IN_EPILOGUE && ii.get_sp_offset () != 0)
++ {
++ log ("(f) adjusting exit sp\n");
++ rtx pattern = gen_rtx_SET(
++ a7, gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, -ii.get_sp_offset ())));
++ emit_insn_before (pattern, ii.get_insn ());
++ }
++ }
++
++ /* convert all parameter accesses via a5 into a7. */
++ for (unsigned i = 0; i < infos.size (); ++i)
+ {
-+ rtx plus = XEXP(mem, 0);
-+ if (GET_CODE(plus) == PLUS)
++ insn_info & ii = infos[i];
++ if (ii.get_myuse () & (1 << FRAME_POINTER_REGNUM))
+ {
-+ rtx sp = XEXP(plus, 0);
-+ if (REG_P(sp) && REGNO(sp) == 15)
++ ii.a5_to_a7 (a7);
++ if (regs_seen && ii.in_proepi () == IN_EPILOGUE_PARALLEL_POP)
+ {
-+ rtx c = XEXP(plus, 1);
-+ if (CONST_INT_P(c))
++ // exit sp insn needs an +
++ rtx pattern = PATTERN (ii.get_insn ());
++ unsigned sz = XVECLEN(pattern, 0);
++
++ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (sz + 1));
++ unsigned n = 0;
++ for (unsigned j = 0; j < sz; ++j)
+ {
-+ int n = INTVAL(c);
-+ if (n >= paramstart)
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, n - adjust);
++ rtx set = XVECEXP(pattern, 0, j);
++ rtx reg = SET_DEST(set);
++ rtx mem = SET_SRC(set);
++ rtx plus = XEXP(mem, 0);
++ if (n)
++ {
++ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, n);
++ }
++ else
++ {
++ XEXP(mem, 0) = XEXP(plus, 0);
++ }
++ n += GET_MODE_SIZE(GET_MODE(reg));
++ XVECEXP(parallel, 0, j + 1) = set;
+ }
++
++ rtx a = copy_reg (a7, -1);
++ a->frame_related = 1;
++ rtx plus = gen_rtx_PLUS(SImode, a, gen_rtx_CONST_INT (SImode, regs_total_size));
++ rtx set = gen_rtx_SET(a, plus);
++ XVECEXP(parallel, 0, 0) = set;
++ SET_INSN_DELETED(ii.get_insn ());
++ ii.set_insn (emit_insn_after (parallel, ii.get_insn ()));
+ }
+ }
++
++ ii.unset (FRAME_POINTER_REGNUM);
+ }
- }
- }
+
-+ /* restore stack insns */
-+ clear_temp ();
++ update_insn2index ();
++ ++changed;
++ }
++ }
+
- return 0;
- }
-
-@@ -1420,7 +1688,7 @@ namespace
- opt_pass *
- clone ()
- {
-- pass_bbb_optimizations * bbb = new pass_bbb_optimizations (m_ctxt);
-+ pass_bbb_optimizations * bbb = new pass_bbb_optimizations (m_ctxt);
- // bbb->pp = pp + 1;
- return bbb;
- }
-@@ -1432,7 +1700,6 @@ namespace
- };
- // class pass_bbb_optimizations
-
--
- /* Main entry point to the pass. */
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
-@@ -1441,54 +1708,58 @@ namespace
- df_note_add_problem ();
- df_analyze ();
-
-- update_meta_data ();
--
-- bool do_opt_strcpy = strchr(flag_bbb_opts, 's') || strchr(flag_bbb_opts, '*');
-- bool do_commute_add_move = strchr(flag_bbb_opts, 'a') || strchr(flag_bbb_opts, '*');
-- bool do_propagate_moves = strchr(flag_bbb_opts, 'p') || strchr(flag_bbb_opts, '*');
-- bool do_const_cmp_to_sub = strchr(flag_bbb_opts, 'c') || strchr(flag_bbb_opts, '*');
-- bool do_merge_add = strchr(flag_bbb_opts, 'm') || strchr(flag_bbb_opts, '*');
-- bool do_elim_dead_assign = strchr(flag_bbb_opts, 'e') || strchr(flag_bbb_opts, '*');
-- bool do_bb_reg_rename = strchr(flag_bbb_opts, 'r') || strchr(flag_bbb_opts, '*');
-+ update_insns ();
-
-+ bool do_opt_strcpy = strchr (flag_bbb_opts, 's') || strchr (flag_bbb_opts, '*');
-+ bool do_commute_add_move = strchr (flag_bbb_opts, 'a') || strchr (flag_bbb_opts, '*');
-+ bool do_propagate_moves = strchr (flag_bbb_opts, 'p') || strchr (flag_bbb_opts, '*');
-+ bool do_const_cmp_to_sub = strchr (flag_bbb_opts, 'c') || strchr (flag_bbb_opts, '*');
-+ bool do_merge_add = strchr (flag_bbb_opts, 'm') || strchr (flag_bbb_opts, '*');
-+ bool do_elim_dead_assign = strchr (flag_bbb_opts, 'e') || strchr (flag_bbb_opts, '*');
-+ bool do_bb_reg_rename = strchr (flag_bbb_opts, 'r') || strchr (flag_bbb_opts, '*');
-+ bool do_shrink_stack_frame = strchr (flag_bbb_opts, 'f') || strchr (flag_bbb_opts, '*');
-
- for (;;)
- {
- int done = 1;
- if (do_opt_strcpy && opt_strcpy ())
-- done = 0, update_meta_data ();
-+ done = 0, update_insns ();
-
- if (do_commute_add_move && commute_add_move ())
-- done = 0, update_meta_data ();
-+ done = 0, update_insns ();
-
- if (do_propagate_moves && propagate_moves ())
-- done = 0, update_meta_data ();
--
--// if (offset_2_autoinc ())
--// done = 0, update_meta_data ();
-+ done = 0, update_insns ();
-
-+ update_insn_infos ();
- if (do_const_cmp_to_sub && const_cmp_to_sub ())
-- done = 0, update_meta_data ();
-+ done = 0, update_insns (), update_insn_infos ();
-
- if (do_merge_add && merge_add ())
-- done = 0, update_meta_data ();
-+ done = 0, update_insns (), update_insn_infos ();
-
- if (do_elim_dead_assign && elim_dead_assign ())
-- done = 0, update_meta_data ();
-+ done = 0, update_insns ();
-
--// if (do_bb_reg_rename && bb_reg_rename ())
--// done = 0, update_meta_data ();
- if (done)
- break;
- }
-
- if (do_bb_reg_rename && ::global_pass_regrename)
- {
-- class opt_pass * rr = ::global_pass_regrename->clone();
-- rr->execute(0);
-+ class opt_pass * rr = ::global_pass_regrename->clone ();
-+ rr->execute (0);
-+ update_insns ();
-+ }
++ return changed;
++}
+
-+ if (do_shrink_stack_frame)
-+ {
-+ shrink_stack_frame ();
-+ update_insns ();
- }
-
-- if (strchr(flag_bbb_opts, 'X')) dump_insns ("bbb 1");
-+ if (strchr (flag_bbb_opts, 'X') || strchr (flag_bbb_opts, 'x'))
-+ dump_insns ("bbb 1", strchr (flag_bbb_opts, 'X'));
- clear ();
-
- return 0;
-diff --git a/gcc/passes.def b/gcc/passes.def
-index ca5b94552d4e..5b78cbd7fb38 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -446,7 +446,6 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_split_after_reload);
- NEXT_PASS (pass_ree);
- NEXT_PASS (pass_compare_elim_after_reload);
-- NEXT_PASS (pass_bbb_optimizations);
- NEXT_PASS (pass_branch_target_load_optimize1);
- NEXT_PASS (pass_jump2);
- NEXT_PASS (pass_duplicate_computed_gotos);
-
-From dcfedefbc4883ebaf068b40920b7830971d02923 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Apr 2017 18:01:13 +0200
-Subject: [PATCH 064/303] @B various bugs, shrink stack frame supports also
- fp-regs
-
----
- gcc/bbb-opts.c | 300 +++++++++++++++++++++++++++++++++++++++++++++------------
- 1 file changed, 238 insertions(+), 62 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 6114e2fa5ed0..c688ca8ae192 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -43,9 +43,11 @@
- #include "recog.h"
- #include "cfgrtl.h"
- #include "emit-rtl.h"
-+#include "tree.h"
- #include "tree-pass.h"
- #include "conditions.h"
- #include "cselib.h"
-+#include "langhooks.h"
- #include <vector>
- #include <map>
-
-@@ -158,10 +160,16 @@ struct insn_info
- unsigned
- get_def_mask () const
- {
-- if (!_def || _def > 0xffff)
-+ if (!_def || _def > 0x7fff)
- return 0;
-
- unsigned mask = _def - 1;
-+ /* more than one register -> don't touch. */
-+ if ((mask & ~_def) != mask)
-+ return 0;
++/* Update the insn_infos to 'know' the value for each register.
++ *
++ * assignments to registers are optimized by knowing the value. If the same value is assigned, omit that insn.
++ *
++ * I'm tracking
++ *
++ * rtx - the value
++ *
++ * mask - the referenced registers in the value, 0 means that rtx is const, with baserel a4 is not tracked
++ *
++ * if there is a value for the referenced register(s), the value is extended
++ *
++ * e.g.
++ *
++ * ; line 2
++ * move.l 12(a7),a0
++ *
++ * -> rtx = mem(plus(a7, 12)); 0x8000
++ *
++ * ; line 10
++ * move.l 4(a0),d0
++ *
++ * -> rtx = mem(plus(mem(plus(a7, 12)), 4)); 0x8000; extended with value from a0, thus a7 is used only
++ *
++ * ;15
++ * lea _label,a1
++ *
++ * -> rtx = symbol_ref(_label) ; 0x0000 == const
++ *
++ * on jumps the current state is duplicated and merged at the given label
++ *
++ * on merge only identical info is kept, rest is discarded
++ *
++ * for each insn for all defined regs the value and mask is discarded before a new value is set.
++ *
++ * for each insn which is writing to memory, all non const values are discarded.
++ *
++ *
++ * after the track info is complete, each insn setting a register is evaluated against the track info.
++ *
++ * now redundant loads are found and eliminated
++ *
++ */
+
-+ if (_def > 0x1000)
-+ return 0;
- if (_def > 0xff)
- mask &= 0xff00;
- return mask;
-@@ -349,6 +357,19 @@ update_insns ()
- }
- }
-
-+extern struct lang_hooks lang_hooks;
-+extern tree current_function_decl;
-+static char const *
-+getCurrentFunctionName ()
++static unsigned
++track_regs ()
+{
-+ static char fxname[512];
-+ if (current_function_decl == NULL)
-+ strcpy (fxname, "<toplevel>");
-+ else
-+ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2));
-+ return fxname;
-+}
++// reset visited flags
++ for (unsigned index = 0; index < infos.size (); ++index)
++ {
++ insn_info & ii = infos[index];
++ ii.clear_visited ();
++ ii.set_sp_offset (0);
++ }
+
- static void
- update_insn_infos (void)
- {
-@@ -401,24 +422,44 @@ update_insn_infos (void)
-
- if (CALL_P(insn))
- {
-+ insn_info def;
-+ insn_info use;
-+
- /* a call sets d0 and maybe also d1,a0,a1. */
-- ii.unset (0);
-- ii.unset (1);
-- ii.unset (8);
-- ii.unset (9);
-+ if (ii.is_use(0))
-+ def.def (0);
-+ if (ii.is_use (1))
-+ {
-+ fprintf (stderr, ":bbb: use of d1 after call in %s\n", getCurrentFunctionName ());
-+ def.def (1);
-+ }
-+ if (ii.is_use (8))
++ update_label2jump ();
++
++// add entry point
++ std::multimap<unsigned, track_var *> todo;
++ todo.insert (std::make_pair (0, new track_var ()));
++
++ while (todo.begin () != todo.end ())
++ {
++ unsigned startpos = todo.begin ()->first;
++ track_var * const track = todo.begin ()->second;
++ todo.erase (todo.begin ());
++
++ for (unsigned index = startpos; index < infos.size (); ++index)
++ {
++ insn_info & ii = infos[index];
++
++ // already visited?
++ if (index != startpos && ii.is_visited () && ii.get_track_var ()->no_merge_needed (track))
++ break;
++
++ // only keep common values at labels
++ if (ii.is_label ())
++ {
++ if (ii.is_visited ())
+ {
-+ fprintf (stderr, ":bbb: use of a0 after call in %s\n", getCurrentFunctionName ());
-+ def.def (8);
++ ii.get_track_var ()->merge (track, index);
+ }
-+ if (ii.is_use (9))
++ else
+ {
-+ fprintf (stderr, ":bbb: use of a1 after call in %s\n", getCurrentFunctionName ());
-+ def.def (9);
++ ii.get_track_var ()->assign (track);
++ ii.mark_visited ();
+ }
-
- // FIXME: isuse the DECL and read attributes.
- // use regs depending on flag mregparm
- for (int i = 0; i < amigaos_regparm; ++i)
- {
-- ii.use (i);
-- ii.use (i + 8);
-+ use.use (i);
-+ use.use (i + 8);
- }
-
- // check for reg use
-- ii.scan (pattern);
-+ use.scan (pattern);
++ continue;
++ }
+
-+ infos[pos] = def | use | ii;
++ // mark current insn_info and set sp_offset
++ ii.mark_visited ();
++ ii.get_track_var ()->assign (track);
+
-+ ii &= ~def;
-+ ii |= use;
-
-- infos[pos] = ii;
- continue;
- }
-
-@@ -720,8 +761,9 @@ propagate_moves ()
- rtx_insn * after = insns[index + 1];
- rtx bset = single_set (before);
-
-- fprintf (stderr, ":bbb: propagate_moves condition met, moving regs %d, %d\n",
-- REGNO(srci), REGNO(dsti));
-+ fprintf (stderr, ":bbb: propagate_moves condition met, moving regs %s, %s\n",
-+ reg_names[REGNO(srci)],
-+ reg_names[REGNO(dsti)]);
-
- /* Move in front of loop and mark as dead. */
- rtx_insn * newii = make_insn_raw (PATTERN (ii));
-@@ -752,8 +794,6 @@ propagate_moves ()
- j = reg_reg.end ();
- inc = false;
-
--// df_insn_rescan (ii);
--// df_insn_rescan (jj);
- df_insn_rescan (newii);
- df_insn_rescan (newjj);
-
-@@ -813,11 +853,17 @@ opt_strcpy ()
- rtx_insn * insn = insns[index];
-
- if (!NONJUMP_INSN_P(insn))
-- continue;
-+ {
-+ x2reg = 0;
-+ continue;
-+ }
-
- rtx set = single_set (insn);
- if (!set)
-- continue;
-+ {
-+ x2reg = 0;
-+ continue;
-+ }
-
- if (x2reg && reg2x)
- {
-@@ -845,8 +891,8 @@ opt_strcpy ()
-
- fprintf (
- stderr,
-- ":bbb: opt_strcpy condition met, removing compare and joining insns - omit reg %d\n",
-- REGNO(dst));
-+ ":bbb: opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
-+ reg_names[REGNO(dst)]);
-
- SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
-
-@@ -1040,15 +1086,12 @@ const_cmp_to_sub (void)
- // FEATURE: check if the next uses are also a add/sub
- // then maybe that add/sub can be adjusted too
-
-- // if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
-- // continue;
-- // use own reg_dead
-+// if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
-+// continue;
-+ /* use own reg_dead - reg_notes seem to be inaccurate!? */
- if (!is_reg_dead (REGNO(left), index) || !is_reg_dead (REGNO(right), index))
- continue;
-
-- fprintf (stderr, ":bbb: found reg-reg compare with both dead: %d %d\n", is_reg_dead (REGNO(left), index),
-- is_reg_dead (REGNO(right), index));
--
- // maybe add a search?
- rtx_insn * prev = insns[index - 1];
- rtx setp = single_set (prev);
-@@ -1087,12 +1130,6 @@ const_cmp_to_sub (void)
- SET_INSN_DELETED(prev);
- prev = emit_insn_before (neuprev, insn);
-
--// urks - unknown side effects
--// int omitted_regno = REGNO(dstp);
--// cselib_invalidate_rtx (dstp);
--// if (!(df->hard_regs_live_count[omitted_regno] -= 2))
--// df_set_regs_ever_live (omitted_regno, false);
--
- fprintf (stderr, ":bbb: const_cmp_to_sub replaced reg-reg compare with sub\n");
-
- if (dstp != left)
-@@ -1188,7 +1225,7 @@ elim_dead_assign (void)
-
- if (is_reg_dead (REGNO(dst), index))
- {
-- fprintf (stderr, ":bbb: elim_dead_assign to %d\n", REGNO(dst));
-+ fprintf (stderr, ":bbb: elim_dead_assign to %s\n", reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
- ++change_count;
- }
-@@ -1311,6 +1348,8 @@ shrink_stack_frame (void)
-
- bool usea5 = false;
- unsigned paramstart = 4;
-+ int a5offset = 0;
++ if (ii.is_compare ())
++ continue;
+
- /*
- * Move prologue to temp.
- * Only register push and parallel insn unless its a link a5 are moved.
-@@ -1333,8 +1372,12 @@ shrink_stack_frame (void)
- rtx set = XVECEXP(pattern, 0, 0);
- rtx dst = SET_DEST(set);
- /* ignore link a5 */
-- if (REG_P(dst) && REGNO(dst) == 13)
-- usea5 = true;
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
++ unsigned def = ii.get_def () & 0xffffff;
++ if (def)
+ {
-+ usea5 = true;
-+ set = XVECEXP(pattern, 0, 2);
-+ a5offset = INTVAL(XEXP(SET_SRC(set), 1));
++ // more than one register set? or mask from clobber?
++ if (((def - 1) & def) || !ii.get_dst_reg ())
++ track->clear_for_mask (def, index);
+ }
- else
- {
- /* use movem */
-@@ -1361,7 +1404,7 @@ shrink_stack_frame (void)
- if (GET_CODE(predec) == PRE_DEC)
- {
- rtx reg = XEXP(predec, 0);
-- if (REG_P(reg) && REGNO(reg) == 15)
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
- {
- temp[pos] = insn;
- insns[pos] = 0;
-@@ -1369,12 +1412,12 @@ shrink_stack_frame (void)
- }
- }
- }
-- else if (GET_CODE(src) == PLUS && REG_P(dest) && REGNO(dest) == 15)
-+ else if (GET_CODE(src) == PLUS && REG_P(dest) && REGNO(dest) == STACK_POINTER_REGNUM)
- {
- /* check for stack variables. */
- rtx reg = XEXP(src, 0);
- rtx cx = XEXP(src, 1);
-- if (REG_P(reg) && REGNO(reg) == 15 && CONST_INT_P(cx))
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM && CONST_INT_P(cx))
- paramstart -= INTVAL(cx);
- }
-
-@@ -1390,6 +1433,8 @@ shrink_stack_frame (void)
-
- unsigned prologueend = pos;
-
-+ prev = insn;
++ // do not clear if self assigned
++ int dregno = ii.get_dst_regno ();
++ if (dregno != ii.get_src_regno ())
++ track->clear (ii.get_mode (), dregno, index);
+
- /* search epilogues - there can be multiple epilogues. */
- while (pos < insns.size ())
- {
-@@ -1406,6 +1451,7 @@ shrink_stack_frame (void)
- ++pos;
- }
-
++ if (ii.is_call ())
++ {
++ track->clear_aftercall (index);
++ continue;
++ }
+
- /* move epilogues away. */
- for (; pos < insns.size (); ++pos)
- {
-@@ -1423,7 +1469,7 @@ shrink_stack_frame (void)
- rtx set = XVECEXP(pattern, 0, 0);
- rtx dst = SET_DEST(set);
- /* unlink is last. */
-- if (REG_P(dst) && REGNO(dst) == 13)
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
- break;
-
- /* movem. */
-@@ -1443,7 +1489,7 @@ shrink_stack_frame (void)
- if (GET_CODE(postinc) == POST_INC)
- {
- rtx reg = XEXP(postinc, 0);
-- if (REG_P(reg) && REGNO(reg) == 15)
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
- {
- temp[pos] = insn;
- insns[pos] = 0;
-@@ -1453,6 +1499,7 @@ shrink_stack_frame (void)
- }
- }
- }
-+ prev = insn;
- ++pos;
- }
- /* gather usage stats without prologue/epilogue */
-@@ -1462,7 +1509,8 @@ shrink_stack_frame (void)
- ii |= infos[i];
- unsigned freemask = ~ii._use;
-
-- rtx a7 = gen_raw_REG (SImode, 15);
-+ rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
-+ rtx a5 = gen_raw_REG (SImode, FRAME_POINTER_REGNUM);
-
- unsigned adjust = 0;
- /* now all push/pop insns are in temp. */
-@@ -1501,7 +1549,8 @@ shrink_stack_frame (void)
- unsigned regbit = 1 << REGNO(reg);
- if (freemask & regbit)
- {
-- fprintf (stderr, i < prologueend ? "remove push for %d\n" : "remove pop for %d\n", REGNO(reg));
-+ fprintf (stderr, i < prologueend ? ":bbb: remove push for %s\n" : ":bbb: remove pop for %s\n",
-+ reg_names[REGNO(reg)]);
- if (i < prologueend)
- adjust += 4;
- }
-@@ -1510,11 +1559,12 @@ shrink_stack_frame (void)
- }
-
- /* don't touch - clobbers! */
-- if (clobbers.size())
-+ if (clobbers.size ())
- continue;
-
- if ((int) regs.size () + 1 < XVECLEN(pattern, 0) || regs.size () <= 2)
- {
-+ fprintf (stderr, ":bbb: shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0), regs.size () + 1);
- if (regs.size () <= 2)
- {
- for (unsigned k = 0; k < regs.size (); ++k)
-@@ -1523,16 +1573,16 @@ shrink_stack_frame (void)
- if (i < prologueend)
- {
- /* push */
-- rtx dec = gen_rtx_PRE_DEC(SImode, a7);
-- rtx mem = gen_rtx_MEM (SImode, dec);
-+ rtx dec = gen_rtx_PRE_DEC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
- rtx set = gen_rtx_SET(mem, reg);
- emit_insn_after (set, insn);
- }
- else
- {
- /* pop */
-- rtx dec = gen_rtx_POST_INC(SImode, a7);
-- rtx mem = gen_rtx_MEM (SImode, dec);
-+ rtx dec = gen_rtx_POST_INC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
- rtx set = gen_rtx_SET(reg, mem);
- emit_insn_before (set, insn);
- }
-@@ -1540,14 +1590,24 @@ shrink_stack_frame (void)
- }
- else
- {
-- rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + 1));
-- int x = regs.size () * 4 + 4;
-+ /* add romm for add. */
-+ int add1 = i < prologueend || !usea5 ? 1 : 0;
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1));
-+ rtx plus;
++ rtx set = single_set (ii.get_insn ());
++
++ // add all referred labels
++ if (ii.is_jump ())
++ {
++ if (ANY_RETURN_P(ii.get_insn ()))
++ break;
++
++ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i)
++ todo.insert (std::make_pair (i->second, new track_var (track)));
++
++ if (set && GET_CODE(SET_SRC(set)) == IF_THEN_ELSE)
++ continue;
++
++ // unconditional jump
++ break;
++ }
++
++ if (!set || !ii.get_def ())
++ continue;
++
++ if (dregno < 0)
++ {
++ track->invalidate_mem (SET_DEST(set));
++ continue;
++ }
++
++ // operation, autoinf or more than one register used: can't cache
++ if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) & ii.get_myuse ()))
++ continue;
++
++ rtx src = SET_SRC(set);
++ if (ii.is_src_mem () && src->volatil)
++ continue;
++
++ track->set (ii.get_mode (), dregno, src, index);
++ }
++ delete track;
++ }
++ return 0;
++}
+
-+ int x = 0;
-+ for (unsigned k = 0; k < regs.size (); ++k)
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-
-- rtx plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-- XVECEXP(parallel, 0, 0) = gen_rtx_SET(a7, plus);
-+ /* no add if a5 is used with pop */
-+ if (!usea5 || i < prologueend)
-+ {
-+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-+ XVECEXP(parallel, 0, 0) = gen_rtx_SET(a7, plus);
-+ }
-
- if (i >= prologueend)
-- x = 0;
-+ x = usea5 ? -x : 0;
-
- for (unsigned k = 0; k < regs.size (); ++k)
- {
-@@ -1555,19 +1615,30 @@ shrink_stack_frame (void)
- {
- /* push */
- plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, -x));
-- x -= 4;
-- rtx mem = gen_rtx_MEM (SImode, plus);
-+ x -= REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
- rtx set = gen_rtx_SET(mem, regs[k]);
- XVECEXP(parallel, 0, k + 1) = set;
- }
- else
- {
- /* pop */
-- plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
-- x += 4;
-- rtx mem = gen_rtx_MEM (SImode, plus);
-- rtx set = gen_rtx_SET(regs[k], mem);
-- XVECEXP(parallel, 0, k + 1) = set;
-+ if (usea5)
-+ {
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-+ rtx set = gen_rtx_SET(regs[k], mem);
-+ XVECEXP(parallel, 0, k) = set;
-+ }
-+ else
-+ {
-+ plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-+ rtx set = gen_rtx_SET(regs[k], mem);
-+ XVECEXP(parallel, 0, k + 1) = set;
-+ }
- }
- }
- emit_insn_after (parallel, insn);
-@@ -1582,13 +1653,13 @@ shrink_stack_frame (void)
- if (i < prologueend)
- {
- /* move x,-(a7). */
-- paramstart += 4;
- rtx src = SET_SRC(set);
-+ paramstart += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
- unsigned regbit = 1 << REGNO(src);
- if (freemask & regbit)
- {
-- adjust += 4;
-- fprintf (stderr, "remove push for %d\n", REGNO(src));
-+ adjust += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
-+ fprintf (stderr, ":bbb: remove push for %s\n", reg_names[REGNO(src)]);
- SET_INSN_DELETED(insn);
- }
- }
-@@ -1599,7 +1670,7 @@ shrink_stack_frame (void)
- unsigned regbit = 1 << REGNO(dst);
- if (freemask & regbit)
- {
-- fprintf (stderr, "remove pop for %d\n", REGNO(dst));
-+ fprintf (stderr, ":bbb: remove pop for %s\n", reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
- }
- }
-@@ -1626,7 +1697,7 @@ shrink_stack_frame (void)
- if (GET_CODE(plus) == PLUS)
- {
- rtx sp = XEXP(plus, 0);
-- if (REG_P(sp) && REGNO(sp) == 15)
-+ if (REG_P(sp) && REGNO(sp) == STACK_POINTER_REGNUM)
- {
- rtx c = XEXP(plus, 1);
- if (CONST_INT_P(c))
-@@ -1647,6 +1718,99 @@ shrink_stack_frame (void)
- return 0;
- }
-
+/*
-+ * Always prefer lower register numbers within the class.
++ * Some optimizations (e.g. propagate_moves) might result into an unused assignment behind the loop.
++ * delete those insns.
+ */
+static unsigned
-+bb_reg_rename (void)
++opt_elim_dead_assign (int blocked_regno)
+{
-+ for (unsigned index = 0; index < insns.size (); ++index)
++ track_regs ();
++
++ unsigned change_count = 0;
++ for (int index = infos.size () - 1; index >= 0; --index)
+ {
+ insn_info & ii = infos[index];
-+ const unsigned def = ii._def;
-+ unsigned mask = ii.get_def_mask ();
++ if (ii.in_proepi () || !ii.get_dst_reg () || ii.is_compare ())
++ continue;
+
-+ if (!mask)
++ rtx_insn * insn = ii.get_insn ();
++ rtx set = single_set (insn);
++ if (!set)
+ continue;
+
-+ std::vector<unsigned> found;
-+ std::vector<unsigned> todo;
-+ if (index + 1 < insns.size ())
-+ todo.push_back (index + 1);
++ if (ii.get_dst_reg () && REG_NREGS(ii.get_dst_reg ()) == 1 && ii.get_dst_regno () != blocked_regno
++ && is_reg_dead (ii.get_dst_regno (), index))
++ {
++ log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]);
++ SET_INSN_DELETED(insn);
++ ++change_count;
++ continue;
++ }
+
-+ found.push_back (index);
-+ /* a register was defined, follow all branches. */
-+ while (todo.size ())
++ // check for redundant load
++ if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno
++ && (!ii.is_myuse (ii.get_dst_regno ()) || ii.get_dst_regno () == ii.get_src_regno ()))
+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
++ track_var * track = ii.get_track_var ();
+
-+ if (LABEL_P(insns[pos]))
++ rtx src = SET_SRC(set);
++ if (track->equals (ii.get_dst_regno (), src))
+ {
-+ if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
++ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
++ SET_INSN_DELETED(insn);
++ ++change_count;
+ continue;
+ }
+
-+ insn_info & jj = infos[pos];
++ if (ii.get_src_reg () && track->equals (ii.get_src_regno (), SET_DEST(set)))
++ {
++ log ("(e) %d: eliminate redundant reverse load to %s\n", index, reg_names[ii.get_dst_regno ()]);
++ SET_INSN_DELETED(insn);
++ ++change_count;
++ continue;
++ }
++
++ // is there a register holding that value?
++ if (!ii.get_src_reg ())
++ {
++ int aliasRegno = track->find_alias (src);
++ if (aliasRegno >= 0 && aliasRegno != ii.get_dst_regno ())
++ {
++ log ("(e) %d: replace load with %s\n", index, reg_names[aliasRegno]);
++ validate_change (ii.get_insn (), &SET_SRC(set), gen_rtx_REG (ii.get_mode (), aliasRegno), 0);
++ ++change_count;
++ }
++ }
++ }
++ }
++ return change_count;
++}
++
++/*
++ * Convert a series of move into absolute address into register based moves.
++ */
++static unsigned
++opt_absolute (void)
++{
++ unsigned change_count = 0;
++
++ for (unsigned i = 0; i < infos.size (); ++i)
++ {
++ insn_info & ii = infos[i];
+
-+ /* update free regs. */
-+ mask &= ~jj._use;
-+ mask &= ~jj._def;
-+ if (!mask)
++ if (ii.is_compare ())
++ continue;
++
++ if (ii.get_src_op () && ii.is_src_ee () && !ii.get_src_intval ())
++ continue;
++
++ bool is_dst = ii.is_dst_mem () && (ii.has_dst_addr () || ii.get_dst_symbol ()) && !ii.has_dst_memreg ();
++ bool is_src = ii.is_src_mem () && (ii.has_src_addr () || ii.get_src_symbol ()) && !ii.has_src_memreg ();
++
++ if (!is_dst && !is_src)
++ continue;
++
++ if (ii.get_mode () == VOIDmode)
++ continue;
++
++ unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00 & usable_regs;
++ if (!freemask)
++ continue;
++
++ rtx with_symbol = is_dst ? ii.get_dst_symbol () : ii.get_src_symbol ();
++
++ std::vector<unsigned> found;
++ found.push_back (i);
++ int base = ii.get_dst_mem_addr ();
++ int max = base;
++ unsigned j = i + 1;
++ for (; j < infos.size (); ++j)
++ {
++ insn_info & jj = infos[j];
++ /* TODO: continue also at jump target */
++ if (jj.is_jump ())
++ continue;
++ /* TODO: check if label is visited only from jump targets from herein. then the label is ok. */
++ if (jj.is_label ())
++ break;
++
++ unsigned tempmask = freemask & ~(jj.get_use () | jj.get_def ());
++ if (!tempmask)
+ break;
++ freemask = tempmask;
+
-+ /* defined again. */
-+ if (jj._def & def)
++ if (jj.get_mode () == VOIDmode || jj.is_compare ())
+ continue;
+
-+ /* not referenced. */
-+ if (!(jj._use & def))
++ if (jj.get_src_op () && jj.is_src_ee () && !jj.get_src_intval ())
+ continue;
+
-+ found.push_back (pos);
++ bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ()) && !jj.has_dst_memreg ()
++ && jj.get_dst_symbol () == with_symbol;
++ bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ()) && !jj.has_src_memreg ()
++ && jj.get_src_symbol () == with_symbol;
++
++ /* exclude operations on that symbol. */
+
-+ /* follow jump and/or next insn. */
-+ rtx_insn * insn = insns[pos];
-+ if (JUMP_P(insn))
++ if (j_dst)
+ {
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-+ if (j != insn2index.end ())
-+ todo.push_back (j->second);
++ int addr = jj.get_dst_mem_addr ();
++ if (addr < base)
++ {
++ if (max - addr <= 0x7ffe)
++ {
++ base = addr;
++ found.push_back (j);
++ continue;
++ }
++ }
++ else if (addr - base <= 0x7ffe)
++ {
++ if (addr > max)
++ max = addr;
++ found.push_back (j);
++ continue;
++ }
++ }
++ if (j_src)
++ {
++ int addr = jj.get_src_mem_addr ();
++ if (addr < base)
++ {
++ if (max - addr <= 0x7ffe)
++ {
++ base = addr;
++ found.push_back (j);
++ continue;
++ }
++ }
++ else if (addr - base <= 0x7ffe)
++ {
++ if (addr > max)
++ max = addr;
++ found.push_back (j);
++ continue;
++ }
++ }
++ }
+
-+ rtx jmppattern = PATTERN (insn);
++ if (freemask && found.size () > 2)
++ {
++ unsigned regno = bit2regno (freemask);
++ /* check again. */
++ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();)
++ {
++ insn_info & kk = infos[*k];
++ bool k_dst = kk.is_dst_mem () && (kk.has_dst_addr () || kk.get_dst_symbol ()) && !kk.has_dst_memreg ()
++ && kk.get_dst_symbol () == with_symbol;
++ bool k_src = kk.is_src_mem () && (kk.has_src_addr () || kk.get_src_symbol ()) && !kk.has_src_memreg ()
++ && kk.get_src_symbol () == with_symbol;
++ if (k_dst && kk.get_dst_mem_addr () - base > 0x7ffc)
++ k = found.erase (k);
++ else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
++ k = found.erase (k);
++ else if (insn_invalid_p (make_insn_raw (kk.make_absolute2base (regno, base, with_symbol, false)), 0))
++ k = found.erase (k);
++ else
++ ++k;
++ }
++ }
++ if (freemask && found.size () > 2)
++ {
++ unsigned regno = bit2regno (freemask);
++ if (with_symbol)
++ log ("(b) modifying %d symbol addresses for %s using %s\n", found.size (),
++ with_symbol->u.block_sym.fld[0].rt_str, reg_names[regno]);
++ else
++ log ("(b) modifying %d absolute addresses using %s\n", found.size (), reg_names[regno]);
++
++ unsigned current_use = ii.get_use ();
++
++ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end (); ++k)
++ {
++ insn_info & kk = infos[*k];
++ kk.absolute2base (regno, base, with_symbol);
++ insn_invalid_p (kk.get_insn (), 0);
++ }
++
++ // load base into reg
++ rtx lea;
++
++ if (with_symbol)
++ {
++ if (base)
++ lea = gen_rtx_SET(
++ gen_raw_REG (SImode, regno),
++ gen_rtx_CONST (SImode, gen_rtx_PLUS (SImode, with_symbol, gen_rtx_CONST_INT (SImode, base))));
++ else
++ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), with_symbol);
++ }
++ else
++ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
++ rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
++ insn_info nn (insn);
++ nn.set_use (current_use);
++ nn.scan ();
++ nn.fledder (lea);
++ nn.mark_def (regno);
++ infos.insert (infos.begin () + i, nn);
+
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-+ if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
++ /* mark until last hit is found. */
++ for (unsigned k = i + 1; k < infos.size (); ++k)
++ {
++ infos[k].mark_use (regno);
++ if (k == *found.rbegin ())
++ break;
+ }
-+ else if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
++ ++change_count;
++ --i;
+ }
++ }
+
-+ if (mask)
++ if (change_count)
++ update_insn2index ();
++
++ return change_count;
++}
++
++static int
++try_auto_inc (unsigned index, insn_info & ii, rtx reg)
++{
++ int const regno = REGNO(reg);
++ unsigned size = GET_MODE_SIZE(ii.get_mode ());
++ if (size > 4)
++ return 0;
++
++// log ("starting auto_inc search for %s at %d\n", reg_names[regno], index);
++
++ // track all fixups to modify
++ std::set<unsigned> fixups;
++
++ // all paths to check
++ std::vector<unsigned> todo;
++ todo.push_back (index + 1);
++
++ bool match_size = false;
++ std::set<unsigned> visited;
++ while (todo.size () > 0)
++ {
++ unsigned pos = todo[todo.size () - 1];
++ todo.pop_back ();
++
++ if (pos == index)
++ return 0;
++
++ if (visited.find (pos) != visited.end ())
++ continue;
++ visited.insert (pos);
++
++ for (; pos < infos.size (); ++pos)
+ {
-+ int oldregno = bit2regno (def);
-+ int newregno = bit2regno (mask);
-+ fprintf (stderr, ":bbb: bb_reg_rename %s -> %s (%d insns)\n", reg_names[oldregno], reg_names[newregno],
-+ found.size ());
++ insn_info & jj = infos[pos];
+
-+ for (std::vector<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
++ // check all jumps labels for register usage
++ if (jj.is_label ())
+ {
-+ debug_rtx (insns[*i]);
-+ do_reg_rename (PATTERN (insns[*i]), oldregno, newregno);
++ for (l2j_iterator j = label2jump.find (jj.get_insn ()->u2.insn_uid), k = j;
++ j != label2jump.end () && j->first == k->first; ++j)
++ {
++ insn_info * ll = insn2info.find (j->second)->second;
++ if (ll->is_use (regno))
++ return 0;
++ }
++ break;
+ }
+
-+ cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
-+ cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
-+ return 1;
++ // break if no longer used
++ if (!jj.is_use (regno))
++ break;
++
++ if (jj.in_proepi ())
++ return 0;
++
++ // add all labels
++ if (jj.is_jump ())
++ {
++ for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end () && j->first == k->first; ++j)
++ todo.push_back (j->second);
++ continue;
++ }
++
++ // not used directly
++ if (!jj.is_myuse (regno))
++ continue;
++
++ // can't fixup such kind of insn (yet)
++ if (single_set (jj.get_insn ()) == 0)
++ return 0;
++
++ // if reg is src reg, op must be add and addend must be large enough
++ bool fix = false;
++ if (jj.get_src_mem_regno () == regno)
++ {
++ if (jj.get_dst_regno () == regno)
++ return 0;
++
++ if (jj.get_src_mem_addr () < size)
++ return 0;
++
++ if (jj.get_src_mem_addr () == size)
++ match_size = true;
++
++ fix = true;
++ }
++ if (jj.get_dst_mem_regno () == regno)
++ {
++ if (jj.get_src_regno () == regno)
++ return 0;
++
++ if (jj.get_dst_mem_addr () < size)
++ return 0;
++
++ if (jj.get_dst_mem_addr () == size)
++ match_size = true;
++
++ fix = true;
++ }
++
++ if (!fix)
++ return 0;
++
++ fixups.insert (pos);
++
++ // done if this is an add
++ if (ii.is_def (regno))
++ break;
+ }
+ }
-+ return 0;
++
++ if (!match_size || !fixups.size ())
++ return 0;
++
++ if (!ii.make_post_inc (regno))
++ return 0;
++
++ log ("(i) auto_inc for %s at %d - %d fixups\n", reg_names[regno], index, fixups.size ());
++
++ // fix all offsets / adds
++ for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
++ {
++// log ("(i) fixup at %d\n", *k);
++ insn_info & kk = infos[*k];
++ kk.auto_inc_fixup (regno, size);
++ }
++ return 1;
+}
+
-+extern const char * current_function_func_begin_label;
- extern class opt_pass * global_pass_regrename;
-
- namespace
-@@ -1676,7 +1840,10 @@ namespace
- virtual bool
- gate (function *)
- {
-- return TARGET_AMIGA && flag_bbb_opts;
-+ if (!flag_bbb_opts)
-+ flag_bbb_opts = "*";
++/*
++ * Convert a series of reg with offset ( (ax), 4(ax), 8(ax), ...) into autoincx ( (ax+), (ax+), (ax+), ...)
++ *
++ * 1. search a mem(reg) without offset and either src or dst is using that reg
++ * 2. follow paths until reg is dead
++ * 3. if there is another mem(reg) with offset check that
++ * a) offset fits last mode size
++ * b) all remaining insn using that reg can be updated by
++ * i) decrement the offset
++ * ii) decrement the add value
++ */
++static unsigned
++opt_autoinc ()
++{
++ unsigned change_count = 0;
+
-+ return TARGET_AMIGA && optimize > 0 && flag_bbb_opts;
- }
-
- virtual unsigned int
-@@ -1704,6 +1871,10 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
++ update_label2jump ();
+
-+ if (strchr (flag_bbb_opts, 'X') || strchr (flag_bbb_opts, 'x'))
-+ fprintf (stderr, "%s:\n", current_function_func_begin_label);
++ for (unsigned index = 0; index < infos.size (); ++index)
++ {
++ insn_info & ii = infos[index];
+
- df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
- df_note_add_problem ();
- df_analyze ();
-@@ -1749,6 +1920,11 @@ namespace
- {
- class opt_pass * rr = ::global_pass_regrename->clone ();
- rr->execute (0);
++ if (ii.in_proepi ())
++ continue;
+
-+// update_insns ();
-+// update_insn_infos ();
-+// bb_reg_rename ();
++ if (!INSN_P(ii.get_insn ()))
++ continue;
+
- update_insns ();
- }
-
-
-From 56aa60f1154c2988edf35ba30ec259a798ba61f2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 13 Apr 2017 23:49:13 +0200
-Subject: [PATCH 065/303] @B fix stack frame handling and suspicious other
- stuff
-
----
- gcc/bbb-opts.c | 80 ++++++++++++++++++++++++++++++----------------------------
- gcc/final.c | 7 ++++-
- 2 files changed, 48 insertions(+), 39 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index c688ca8ae192..56251b906184 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -182,7 +182,8 @@ insn_info::scan (rtx x)
- {
- if (REG_P(x))
- {
-- use (REGNO(x));
-+ for (int n = REG_NREGS(x), r = REGNO(x); n > 0; --n, ++r)
-+ use (r);
- return;
- }
-
-@@ -425,35 +426,34 @@ update_insn_infos (void)
- insn_info def;
- insn_info use;
-
-- /* a call sets d0 and maybe also d1,a0,a1. */
-- if (ii.is_use(0))
-- def.def (0);
-- if (ii.is_use (1))
-- {
-- fprintf (stderr, ":bbb: use of d1 after call in %s\n", getCurrentFunctionName ());
-- def.def (1);
-- }
-- if (ii.is_use (8))
-+ /* add mregparm registers. */
-+ for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
- {
-- fprintf (stderr, ":bbb: use of a0 after call in %s\n", getCurrentFunctionName ());
-- def.def (8);
-- }
-- if (ii.is_use (9))
-- {
-- fprintf (stderr, ":bbb: use of a1 after call in %s\n", getCurrentFunctionName ());
-- def.def (9);
-+ rtx op, reg;
-+
-+ if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-+ for (int r = REGNO(reg); r <= END_REGNO (reg); ++r)
-+ use.use (r);
- }
-
-- // FIXME: isuse the DECL and read attributes.
-- // use regs depending on flag mregparm
-- for (int i = 0; i < amigaos_regparm; ++i)
-+ rtx set = single_set (insn);
-+ if (set)
- {
-- use.use (i);
-- use.use (i + 8);
-+ use.scan (SET_SRC(set));
-+ def.scan (SET_DEST(set));
- }
-+ else
-+ use.scan (pattern);
-
-- // check for reg use
-- use.scan (pattern);
-+ /* fix missing defs - a call sets d0 and maybe also d1,a0,a1. */
-+ if (ii.is_use (0))
-+ def.def (0);
-+ if (ii.is_use (1))
-+ def.def (1);
-+ if (ii.is_use (8))
-+ def.def (8);
-+ if (ii.is_use (9))
-+ def.def (9);
-
- infos[pos] = def | use | ii;
-
-@@ -494,7 +494,7 @@ update_insn_infos (void)
- continue;
- }
-
-- if (GET_CODE (pattern) != PARALLEL)
-+ if (GET_CODE (pattern) != PARALLEL && GET_CODE (pattern) != CLOBBER)
- {
- fprintf (stderr, "##### ");
- debug_rtx (insn);
-@@ -1062,7 +1062,7 @@ const_cmp_to_sub (void)
- {
- unsigned change_count = 0;
- #if HAVE_cc0
-- for (unsigned index = insns.size () - 2; index > 0; --index)
-+ for (int index = insns.size () - 2; index > 0; --index)
- {
- rtx_insn * insn = insns[index];
- rtx seti = single_set (insn);
-@@ -1079,7 +1079,7 @@ const_cmp_to_sub (void)
-
- rtx left = XEXP(srci, 0);
- rtx right = XEXP(srci, 1);
-- if (!REG_P(left) || !REG_P(right))
-+ if (!REG_P(left) || !REG_P(right) || REG_NREGS(left) > 1 || REG_NREGS(right) > 1)
- continue;
-
- // TODO
-@@ -1451,7 +1451,6 @@ shrink_stack_frame (void)
- ++pos;
- }
-
--
- /* move epilogues away. */
- for (; pos < insns.size (); ++pos)
- {
-@@ -1506,7 +1505,12 @@ shrink_stack_frame (void)
- update_insn_infos ();
- insn_info ii;
- for (unsigned i = 0; i < infos.size (); ++i)
-- ii |= infos[i];
++// // more than one reg used
++// if (ii.get_myuse () & (ii.get_myuse () - 1))
++// continue;
++
++// // don't if fp regs are touched
++// if ((ii.get_myuse () & 0xff0000))
++// continue;
++
++ if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 && !ii.get_src_mem_addr () && !ii.get_src_autoinc ()
++ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () && ii.get_src_mem_regno () != ii.get_dst_regno ())
++ change_count += try_auto_inc (index, ii, ii.get_src_mem_reg ());
++
++ if (ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
++ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () && ii.get_src_regno () != ii.get_dst_mem_regno ())
++ change_count += try_auto_inc (index, ii, ii.get_dst_mem_reg ());
++
++ }
++
++ return change_count;
++}
++
++namespace
++{
++
++ const pass_data pass_data_bbb_optimizations =
++ { RTL_PASS, /* type */
++ "bebbo's-optimizers", /* name */
++ OPTGROUP_NONE, /* optinfo_flags */
++ TV_NONE, /* tv_id */
++ 0, /* properties_required */
++ 0, /* properties_provided */
++ 0, /* properties_destroyed */
++ 0, /* todo_flags_start */
++ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
++ };
++
++ class pass_bbb_optimizations : public rtl_opt_pass
++ {
++ public:
++ pass_bbb_optimizations (gcc::context *ctxt) :
++ rtl_opt_pass (pass_data_bbb_optimizations, ctxt), pp (0)
+ {
-+ insn_info & jj = infos[i];
-+ ii |= jj;
-+// fprintf (stderr, "%08lx %08lx\n", jj._use, jj._def);
+ }
-+// fprintf (stderr, "%08lx %08lx\n", ii._use, ii._def);
- unsigned freemask = ~ii._use;
-
- rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
-@@ -1562,9 +1566,15 @@ shrink_stack_frame (void)
- if (clobbers.size ())
- continue;
-
-- if ((int) regs.size () + 1 < XVECLEN(pattern, 0) || regs.size () <= 2)
-+ /* add romm for add.
-+ * push is always using -(a7) addressing.
-+ * If a5 is used a movem offset(a5) is generated to pop saved registers..
-+ * Otherwise a7 is used and with (a7)+ addressing.
-+ */
-+ int add1 = i < prologueend || !usea5 ? 1 : 0;
-+ if ((int) regs.size () + add1 < XVECLEN(pattern, 0) || regs.size () <= 2)
- {
-- fprintf (stderr, ":bbb: shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0), regs.size () + 1);
-+ fprintf (stderr, ":bbb: shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1, regs.size ());
- if (regs.size () <= 2)
- {
- for (unsigned k = 0; k < regs.size (); ++k)
-@@ -1590,8 +1600,6 @@ shrink_stack_frame (void)
- }
- else
- {
-- /* add romm for add. */
-- int add1 = i < prologueend || !usea5 ? 1 : 0;
- rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1));
- rtx plus;
-
-@@ -1856,7 +1864,7 @@ namespace
- clone ()
- {
- pass_bbb_optimizations * bbb = new pass_bbb_optimizations (m_ctxt);
-- // bbb->pp = pp + 1;
++
++ /* opt_pass methods: */
++ virtual bool
++ gate (function *)
++ {
++ if (!string_bbb_opts)
++ string_bbb_opts = "+";
++
++ return TARGET_AMIGA && optimize > 0 && string_bbb_opts && !strchr (string_bbb_opts, '-');
++ }
++
++ virtual unsigned int
++ execute (function *)
++ {
++ return execute_bbb_optimizations ();
++ }
++
++ opt_pass *
++ clone ()
++ {
++ pass_bbb_optimizations * bbb = new pass_bbb_optimizations (m_ctxt);
+ bbb->pp = pp + 1;
- return bbb;
- }
-
-@@ -1871,10 +1879,6 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
--
-- if (strchr (flag_bbb_opts, 'X') || strchr (flag_bbb_opts, 'x'))
-- fprintf (stderr, "%s:\n", current_function_func_begin_label);
--
- df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
- df_note_add_problem ();
- df_analyze ();
-diff --git a/gcc/final.c b/gcc/final.c
-index 55cf509611f7..9d21ffc1baff 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -2165,7 +2165,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
-
- /* Ignore deleted insns. These can occur when we split insns (due to a
- template of "#") while not optimizing. */
-- if (insn->deleted ())
-+ if (insn->deleted () || GET_CODE(insn) == VALUE || GET_CODE(insn) == CONST_FIXED)
- return NEXT_INSN (insn);
-
- switch (GET_CODE (insn))
-@@ -4430,12 +4430,17 @@ leaf_renumber_regs_insn (rtx in_rtx)
- }
- #endif
-
++ return bbb;
++ }
+
-+extern void dump_insns(char const *);
++ unsigned int pp;
+
- /* Turn the RTL into assembly. */
- static unsigned int
- rest_of_handle_final (void)
- {
- const char *fnname = get_fnname_from_decl (current_function_decl);
-
-+// dump_insns("final");
-+
- assemble_start_function (current_function_decl, fnname);
- final_start_function (get_insns (), asm_out_file, optimize);
- final (get_insns (), asm_out_file, optimize);
-
-From 51c5b7b668483ac0cdc30a3fee718754a03bcca9 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 14 Apr 2017 18:33:26 +0200
-Subject: [PATCH 066/303] @R add option description for command line help
-
----
- gcc/config/m68k/amigaos.opt | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index a5a14449dea9..9c08ba43196e 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -25,24 +25,24 @@ small code model
-
- fbaserel
- Target Report Var(flag_pic,3)
--data is adressed relativ to a4
-+data is addressed relative to a4
-
- fbaserel32
- Target Report Var(flag_pic,4)
--data is adressed relativ to a4 with 32 bit offsets
-+data is addressed relative to a4 with 32 bit offsets
-
- resident
- Target Common Report Var(flag_pic,3)
--data is adressed relativ to a4, linked as resident
-+data is addressed relative to a4, linked as resident
-
- resident32
- Target Common Report Var(flag_pic,4)
--data is adressed relativ to a4 with 32 bit offsets, linked as resident
-+data is addressed relative to a4 with 32 bit offsets, linked as resident
-
- mcrt=
- Target RejectNegative Var(amigaos_crt) Joined
- Specify startup binary
-
- fbbb=
--Target Var(flag_bbb_opts) Joined
--Enable Bebbo's optimizations
-+Target RejectNegative Report Var(string_bbb_opts) Joined
-+-fbbb=\t\tEnable Bebbo's optimizations. Default: -fbbb=+\n valid letters:\n\t\t+\t\tenable all\n\t\t-\t\tdisable all\n\t\ta\t\tadd move optimization\n\t\tc\t\tcompare to sub\n\t\te\t\teliminate dead assignments\n\t\tf\t\tshrink stack frame\n\t\tm\t\tmerge add statements\n\t\tp\t\tpropagate move pairs from loops\n\t\tr\t\tadditional reg rename pass\n\t\tv\t\tbe verbose\n\t\tx or X\t\tdump insns
-
-From 5abbd0e25e9cc50d4449884567079df90141511b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 14 Apr 2017 18:34:31 +0200
-Subject: [PATCH 067/303] @B resolv issues to get everything built
-
----
- gcc/bbb-opts.c | 255 +++++++++++++++++++--------------------------------------
- gcc/final.c | 2 +-
- gcc/passes.def | 6 +-
- 3 files changed, 89 insertions(+), 174 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 56251b906184..1b1863e9ae8f 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -51,6 +51,42 @@
- #include <vector>
- #include <map>
-
-+static bool be_verbose;
++ unsigned
++ execute_bbb_optimizations (void);
++ };
++// class pass_bbb_optimizations
+
-+extern struct lang_hooks lang_hooks;
-+extern tree current_function_decl;
-+static tree last_function_decl;
-+static char const *
-+getCurrentFunctionName ()
++ /* Main entry point to the pass. */
++ unsigned
++ pass_bbb_optimizations::execute_bbb_optimizations (void)
++ {
++ dump_reg_track = strchr (string_bbb_opts, 'R') != 0;
++ be_very_verbose = strchr (string_bbb_opts, 'V') != 0;
++ be_verbose = strchr (string_bbb_opts, 'v') != 0;
++ if (be_verbose && be_very_verbose)
++ ++be_very_verbose;
++ if (be_very_verbose)
++ be_verbose = true;
++
++ bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
++ bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
++ bool do_const_cmp_to_sub = strchr (string_bbb_opts, 'c') || strchr (string_bbb_opts, '+');
++ bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr (string_bbb_opts, '+');
++ bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
++ bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
++ bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr (string_bbb_opts, '+');
++ bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr (string_bbb_opts, '+');
++ bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
++ bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
++
++ if (be_very_verbose)
++ log ("ENTER\n");
++
++ unsigned r = update_insns ();
++ if (!r)
++ {
++ for (;;)
++ {
++ int done = 1;
++ if (do_opt_strcpy && opt_strcpy ())
++ done = 0, update_insns ();
++
++ if (do_commute_add_move && opt_commute_add_move ())
++ done = 0, update_insns ();
++
++ if (do_propagate_moves && opt_propagate_moves ())
++ done = 0, update_insns ();
++
++ if (do_const_cmp_to_sub && opt_const_cmp_to_sub ())
++ done = 0, update_insns ();
++
++ if (do_merge_add && opt_merge_add ())
++ done = 0;
++
++ if (do_elim_dead_assign && opt_elim_dead_assign (STACK_POINTER_REGNUM))
++ done = 0, update_insns ();
++
++ if (do_absolute && opt_absolute ())
++ done = 0, update_insns ();
++
++ if (do_autoinc && opt_autoinc ())
++ done = 0, update_insns ();
++
++ if (do_bb_reg_rename)
++ {
++ while (opt_reg_rename ())
++ {
++ update_insns ();
++ done = 0;
++ }
++ }
++
++ if (done)
++ break;
++ }
++
++ if (do_shrink_stack_frame)
++ {
++ if (opt_shrink_stack_frame ())
++ update_insns ();
++ }
++
++ /* elim stack pointer stuff last. */
++ if (do_elim_dead_assign)
++ opt_elim_dead_assign (FIRST_PSEUDO_REGISTER);
++ }
++ if (r && be_verbose)
++ log ("no bbb optimization code %d\n", r);
++
++ if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
++ dump_insns ("bbb", strchr (string_bbb_opts, 'X'));
++
++ if (dump_reg_track)
++ {
++ update_insns ();
++ track_regs ();
++ }
++
++ return r;
++ }
++
++} // anon namespace
++
++rtl_opt_pass *
++make_pass_bbb_optimizations (gcc::context * ctxt)
+{
-+ static char fxname[512];
-+ if (current_function_decl == NULL)
-+ strcpy (fxname, "<toplevel>");
-+ else
-+ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2));
-+ return fxname;
++ return new pass_bbb_optimizations (ctxt);
+}
+
-+static int
-+log (char const * fmt, ...)
++namespace
+{
-+ if (!be_verbose)
-+ return 0;
+
-+ va_list args;
-+ va_start(args, fmt);
-+ if (last_function_decl != current_function_decl)
++ const pass_data pass_data_bbb_baserel =
++ { RTL_PASS, /* type */
++ "bebbo's-baserel fixer", /* name */
++ OPTGROUP_NONE, /* optinfo_flags */
++ TV_NONE, /* tv_id */
++ 0, /* properties_required */
++ 0, /* properties_provided */
++ 0, /* properties_destroyed */
++ 0, /* todo_flags_start */
++ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
++ };
++
++ class pass_bbb_baserel : public rtl_opt_pass
++ {
++ public:
++ pass_bbb_baserel (gcc::context *ctxt) :
++ rtl_opt_pass (pass_data_bbb_baserel, ctxt), pp (0)
+ {
-+ last_function_decl = current_function_decl;
-+ printf (":bbb: in '%s'\n", getCurrentFunctionName ());
+ }
-+ printf (":bbb: ");
-+ int retval = vprintf (fmt, args);
-+ va_end(args);
-+ fflush (stdout);
-+ return retval;
-+}
+
- /* Enough for m68k.
- * Why a class? Maybe extend it for general usage.
- *
-@@ -231,21 +267,6 @@ do_reg_rename (rtx x, unsigned oldregno, unsigned newregno)
- }
- }
++ /* opt_pass methods: */
++ virtual bool
++ gate (function *)
++ {
++ return TARGET_AMIGA && flag_pic >= 3;
++ }
++
++ virtual unsigned int
++ execute (function *)
++ {
++ return execute_bbb_baserel ();
++ }
++
++ opt_pass *
++ clone ()
++ {
++ pass_bbb_baserel * bbb = new pass_bbb_baserel (m_ctxt);
++ return bbb;
++ }
++
++ unsigned int pp;
++
++ unsigned
++ execute_bbb_baserel (void);
++ };
++// class pass_bbb_optimizations
++
++ /* Main entry point to the pass. */
++ unsigned
++ pass_bbb_baserel::execute_bbb_baserel (void)
++ {
++ rtx_insn *insn, *next;
++ for (insn = get_insns (); insn; insn = next)
++ {
++ next = NEXT_INSN (insn);
++
++ if (NONJUMP_INSN_P(insn))
++ {
++ rtx set = single_set (insn);
++ if (!set)
++ continue;
++
++ rtx * src = &SET_SRC(set);
++ if (MEM_P(*src))
++ src = &XEXP(*src, 0);
++
++ bool ispicref = false;
++ // fix add PLUS/MINUS into the unspec offset
++ if (GET_CODE(*src) == PLUS || GET_CODE(*src) == MINUS)
++ ispicref = amiga_is_const_pic_ref (XEXP(*src, 0));
++ else
++ ispicref = amiga_is_const_pic_ref (*src);
++
++ if (ispicref)
++ {
++ rtx dest = SET_DEST(set);
++ if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC)
++ {
++ // split the insn
++ rtx reg = gen_reg_rtx (Pmode);
++
++ rtx pat0 = gen_rtx_SET(reg, *src);
++ //rtx_insn * n0 =
++ emit_insn_before (pat0, insn);
++
++ rtx pat1 = gen_rtx_SET(dest, reg);
++ //rtx_insn * n1 =
++ emit_insn_before (pat1, insn);
++
++ SET_INSN_DELETED(insn);
++ }
++ }
++ }
++ }
++
++ return 0;
++ }
++
++} // anon namespace
++
++rtl_opt_pass *
++make_pass_bbb_baserel (gcc::context * ctxt)
++{
++ return new pass_bbb_baserel (ctxt);
++}
+diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
+index e8bafedd7357..642829b828c7 100644
+--- gcc/c/c-decl.c
++++ gcc/c/c-decl.c
+@@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
+ #include "c-family/c-ada-spec.h"
+ #include "cilk.h"
+ #include "builtins.h"
++#include "output.h"
++#include "tm_p.h"
--static int
--bit2regno (unsigned bit)
--{
-- if (!bit)
-- return -1;
--
-- unsigned regno = 0;
-- while (!(bit & 1))
-- {
-- ++regno;
-- bit >>= 1;
-- }
-- return regno;
--}
--
- /*
- * Collect some data.
- */
-@@ -358,19 +379,6 @@ update_insns ()
+ /* In grokdeclarator, distinguish syntactic contexts of declarators. */
+ enum decl_context
+@@ -4439,7 +4441,32 @@ c_decl_attributes (tree *node, tree attributes, int flags)
+ attributes = tree_cons (get_identifier ("omp declare target"),
+ NULL_TREE, attributes);
}
+- return decl_attributes (node, attributes, flags);
++
++ tree returned_attrs = decl_attributes (node, attributes, flags);
++
++#ifdef TARGET_AMIGA
++ /* add an attribute to the function decl's type if there are asm register parameters. */
++ if (TREE_CODE (*node) == FUNCTION_DECL)
++ {
++ char const * synthetic = "";
++ for (tree params = TYPE_ARG_TYPES(TREE_TYPE(*node)); params; params = TREE_CHAIN(params))
++ {
++ tree asmattr = lookup_attribute("asm", TYPE_ATTRIBUTES(TREE_VALUE(params)));
++ if (asmattr)
++ synthetic = concat(synthetic, reg_names[TREE_FIXED_CST_PTR(TREE_VALUE(asmattr))->data.low], NULL);
++ }
++ if (strlen(synthetic) > 0)
++ {
++ tree asmid = get_identifier("asmregs");
++ tree syntheticid = get_identifier(synthetic);
++ tree newattr = tree_cons(asmid, syntheticid, NULL_TREE);
++
++ TYPE_ATTRIBUTES(TREE_TYPE(*node)) = chainon(newattr, TYPE_ATTRIBUTES(TREE_TYPE(*node)));
++ }
++ }
++#endif
++
++ return returned_attrs;
}
--extern struct lang_hooks lang_hooks;
--extern tree current_function_decl;
--static char const *
--getCurrentFunctionName ()
--{
-- static char fxname[512];
-- if (current_function_decl == NULL)
-- strcpy (fxname, "<toplevel>");
-- else
-- strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2));
-- return fxname;
--}
--
- static void
- update_insn_infos (void)
- {
-@@ -432,7 +440,7 @@ update_insn_infos (void)
- rtx op, reg;
-
- if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-- for (int r = REGNO(reg); r <= END_REGNO (reg); ++r)
-+ for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
- use.use (r);
- }
-
-@@ -468,7 +476,7 @@ update_insn_infos (void)
- if (ANY_RETURN_P(pattern))
- {
- ii.reset ();
-- ii.use (0);
-+// ii.use (0);
- }
- else
- {
-@@ -494,7 +502,7 @@ update_insn_infos (void)
- continue;
- }
-
-- if (GET_CODE (pattern) != PARALLEL && GET_CODE (pattern) != CLOBBER)
-+ if (GET_CODE (pattern) != PARALLEL && GET_CODE (pattern) != CLOBBER && be_verbose)
- {
- fprintf (stderr, "##### ");
- debug_rtx (insn);
-@@ -761,9 +769,9 @@ propagate_moves ()
- rtx_insn * after = insns[index + 1];
- rtx bset = single_set (before);
-
-- fprintf (stderr, ":bbb: propagate_moves condition met, moving regs %s, %s\n",
-+ log ("propagate_moves condition met, moving regs %s, %s\n",
- reg_names[REGNO(srci)],
-- reg_names[REGNO(dsti)]);
-+ reg_names[REGNO(dsti)]);
-
- /* Move in front of loop and mark as dead. */
- rtx_insn * newii = make_insn_raw (PATTERN (ii));
-@@ -800,7 +808,7 @@ propagate_moves ()
- /* add fixes if there were jumps out of the loop. */
- if (jump_out.size ())
- {
-- fprintf (stderr, ":bbb: propagate_moves fixing %d jump outs\n", jump_out.size ());
-+ log ("propagate_moves fixing %d jump outs\n", jump_out.size ());
-
- for (unsigned k = 0; k < jump_out.size (); ++k)
- {
-@@ -873,7 +881,8 @@ opt_strcpy ()
- rtx dst = XEXP(src, 0);
- src = XEXP(src, 1);
-
-- if (CONST_INT_P(src) && INTVAL(src) == 0 && find_reg_note (insn, REG_DEAD, dst))
-+// if (CONST_INT_P(src) && INTVAL(src) == 0 && find_reg_note (insn, REG_DEAD, dst))
-+ if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 && is_reg_dead(REGNO(dst), index))
- {
- /* now check via NOTICE_UPDATE_CC*/
- NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
-@@ -889,10 +898,8 @@ opt_strcpy ()
- {
- rtx link;
-
-- fprintf (
-- stderr,
-- ":bbb: opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
-- reg_names[REGNO(dst)]);
-+ log ("opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
-+ reg_names[REGNO(dst)]);
-
- SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
-
-@@ -1017,7 +1024,7 @@ commute_add_move (void)
- if (validate_change (next, &SET_DEST(set2), newmem, 0))
- {
-- fprintf (stderr, ":bbb: commute_add_move found\n");
-+ log ("commute_add_move found\n");
+@@ -5024,6 +5051,29 @@ grokparm (const struct c_parm *parm, tree *expr)
+ return decl;
+ }
- SET_INSN_DELETED(insn);
++#ifdef TARGET_AMIGA
++
++/* Create a new variant of TYPE, equivalent but distinct.
++ This is so the caller can modify it. */
++
++static tree
++build_type_copy (tree type)
++ {
++ tree t, m = TYPE_MAIN_VARIANT (type);
++
++ t = copy_node (type);
++
++ TYPE_POINTER_TO (t) = 0;
++ TYPE_REFERENCE_TO (t) = 0;
++
++ /* Add this type to the chain of variants of TYPE. */
++ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
++ TYPE_NEXT_VARIANT (m) = t;
++
++ return t;
++ }
++#endif
++
+ /* Given a parsed parameter declaration, decode it into a PARM_DECL
+ and push that on the current scope. EXPR is a pointer to an
+ expression that needs to be evaluated for the side effects of array
+@@ -5041,6 +5091,59 @@ push_parm_decl (const struct c_parm *parm, tree *expr)
-@@ -1130,7 +1137,7 @@ const_cmp_to_sub (void)
- SET_INSN_DELETED(prev);
- prev = emit_insn_before (neuprev, insn);
+ decl = pushdecl (decl);
-- fprintf (stderr, ":bbb: const_cmp_to_sub replaced reg-reg compare with sub\n");
-+ log ("const_cmp_to_sub replaced reg-reg compare with sub\n");
++#ifdef TARGET_AMIGAOS
++ if (parm->asmspec)
++ {
++ tree atype = TREE_TYPE(decl);
++ const char *asmspec = TREE_STRING_POINTER(parm->asmspec);
++ if (*asmspec == '%')
++ ++asmspec;
++ int reg_number = decode_reg_name (asmspec);
++
++ /* First detect errors in declaring global registers. */
++ if (reg_number == -1)
++ error ("%Jregister name not specified for %qD", decl, decl);
++ else if (reg_number < 0)
++ error ("%Jinvalid register name for %qD", decl, decl);
++ else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
++ error ("%Jdata type of %qD isn%'t suitable for a register", decl, decl);
++ else if (!HARD_REGNO_MODE_OK(reg_number, TYPE_MODE (TREE_TYPE (decl))))
++ error ("%Jregister specified for %qD isn%'t suitable for data type",
++ decl, decl);
++ /* Now handle properly declared static register variables. */
++ else
++ {
++ /* Build tree for __attribute__ ((asm(regnum))). */
++ FIXED_VALUE_TYPE fv =
++ { reg_number, 0, BImode };
++ tree ttasm = get_identifier("asm");
++ tree t, attrs = tree_cons(ttasm, build_fixed (ttasm, fv), NULL_TREE);
++ /* 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(atype); t; t = TYPE_NEXT_VARIANT(t))
++ if (comptypes (t, atype) == 1
++ && attribute_list_equal (TYPE_ATTRIBUTES(t), attrs))
++ break;
++ if (t)
++ atype = 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). */
++ atype = build_type_copy (atype);
++ TYPE_ATTRIBUTES(atype) = chainon (attrs, TYPE_ATTRIBUTES(atype));
++ }
++ TREE_TYPE(decl) = atype;
++// printf("%s using %s, cdecl=%p, type=%p\n", IDENTIFIER_POINTER(DECL_NAME (decl)), asmspec, decl, atype);
++ }
++ }
++#endif
++
+ finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
+ }
- if (dstp != left)
- {
-@@ -1191,7 +1198,7 @@ const_cmp_to_sub (void)
+diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
+index fc20bad8d992..91cfc2c5e193 100644
+--- gcc/c/c-parser.c
++++ gcc/c/c-parser.c
+@@ -3837,10 +3837,26 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
+ c_parser_skip_until_found (parser, CPP_COMMA, NULL);
+ return NULL;
+ }
++ /**
++ * SBF: Add support for __asm("xy") register spec.
++ */
++#ifdef TARGET_AMIGAOS
++ tree asmspec = NULL_TREE;
++ if (c_parser_next_token_is_keyword (parser, RID_ASM))
++ {
++ asmspec = c_parser_simple_asm_expr (parser);
++// printf("asmspec: %s\n", TREE_STRING_POINTER(asmspec));
++ }
++#endif
+ if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
+ postfix_attrs = c_parser_attributes (parser);
+- return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
++
++ struct c_parm * cparm = build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
+ declarator);
++#ifdef TARGET_AMIGAOS
++ cparm->asmspec = asmspec;
++#endif
++ return cparm;
+ }
- if (code != newcode)
- {
-- fprintf (stderr, ":bbb: patch jcc %d -> %d\n", code, newcode);
-+ log ("patch jcc %d -> %d\n", code, newcode);
- XEXP(jmpsrc, 0) = gen_rtx_fmt_ee(newcode, VOIDmode, XEXP(condition, 0), XEXP(condition, 1));
- }
- }
-@@ -1225,7 +1232,7 @@ elim_dead_assign (void)
+ /* Parse a string literal in an asm expression. It should not be
+@@ -3892,6 +3908,7 @@ c_parser_asm_string_literal (c_parser *parser)
+ static tree
+ c_parser_simple_asm_expr (c_parser *parser)
+ {
++ extern int in_assembler_directive;
+ tree str;
+ gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
+ /* ??? Follow the C++ parser rather than using the
+@@ -3903,7 +3920,13 @@ c_parser_simple_asm_expr (c_parser *parser)
+ parser->lex_untranslated_string = false;
+ return NULL_TREE;
+ }
++
++ // SBF: set in_assembler_directive to enable multi-line strings. And yes, it's a HACK.
++ in_assembler_directive = 1;
+ str = c_parser_asm_string_literal (parser);
++ // SBF: in_assembler_directive disabled
++ in_assembler_directive = 0;
++
+ parser->lex_untranslated_string = false;
+ if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+ {
+diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
+index bb12a200f709..e3404fd8b0a6 100644
+--- gcc/c/c-tree.h
++++ gcc/c/c-tree.h
+@@ -453,6 +453,10 @@ struct c_parm {
+ tree attrs;
+ /* The declarator. */
+ struct c_declarator *declarator;
++#ifdef TARGET_AMIGAOS
++ /* The optional asm spec to specify the register. */
++ tree asmspec;
++#endif
+ };
- if (is_reg_dead (REGNO(dst), index))
+ /* Used when parsing an enum. Initialized by start_enum. */
+diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
+index 6e92d4cdde22..378b1fc595bb 100644
+--- gcc/cfgcleanup.c
++++ gcc/cfgcleanup.c
+@@ -2001,6 +2001,15 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
{
-- fprintf (stderr, ":bbb: elim_dead_assign to %s\n", reg_names[REGNO(dst)]);
-+ log ("elim_dead_assign to %s\n", reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
- ++change_count;
- }
-@@ -1291,13 +1298,15 @@ merge_add (void)
- if (REGNO(dst1) != REGNO(dst2) || REGNO(r2) != REGNO(dst3))
- continue;
+ rtx_insn *insn;
-- fprintf (stderr, ":bbb: merge_add applied\n");
-+ log ("merge_add applied\n");
++#ifdef TARGET_AMIGA
++ /*
++ * we need replicated labels, if the labels are too far away,
++ * since on 68000 there are only 8 bits for the offset.
++ */
++ if (!TARGET_68020 && !TARGET_68040)
++ return false;
++#endif
+
-+ rtx_insn * newins1 = make_insn_raw(gen_rtx_SET(dst1, l1));
-+ add_insn_after (newins1, ins1, 0);
-+ SET_INSN_DELETED(ins1);
+ /* Replace references to LABEL1 with LABEL2. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+@@ -2016,8 +2025,9 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
+ /* Avoid splitting if possible. We must always split when SRC2 has
+ EH predecessor edges, or we may end up with basic blocks with both
+ normal and EH predecessor edges. */
+- if (newpos2 == BB_HEAD (src2)
++ if ((newpos2 == BB_HEAD (src2)
+ && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
++ )
+ redirect_to = src2;
+ else
+ {
+diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
+index b612293b1a7a..4215ae90c63d 100644
+--- gcc/cfgexpand.c
++++ gcc/cfgexpand.c
+@@ -2732,6 +2732,10 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
+ {
+ /* Conflicts between asm-declared register variables and the clobber
+ list are not allowed. */
++ /*
++ * SBF: Why?
++ */
++#ifndef TARGET_AMIGA
+ tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs);
-- SET_SRC(set1) = l1;
- rtx_insn * newins2 = make_insn_raw (PATTERN (ins2));
- add_insn_after (newins2, ins3, 0);
- SET_INSN_DELETED(ins2);
-- df_insn_rescan (ins1);
+ if (overlap)
+@@ -2744,7 +2748,7 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
+ DECL_REGISTER (overlap) = 0;
+ return true;
}
- return change_count;
+-
++#endif
+ return false;
}
-@@ -1508,9 +1517,7 @@ shrink_stack_frame (void)
- {
- insn_info & jj = infos[i];
- ii |= jj;
--// fprintf (stderr, "%08lx %08lx\n", jj._use, jj._def);
- }
--// fprintf (stderr, "%08lx %08lx\n", ii._use, ii._def);
- unsigned freemask = ~ii._use;
- rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
-@@ -1553,7 +1560,7 @@ shrink_stack_frame (void)
- unsigned regbit = 1 << REGNO(reg);
- if (freemask & regbit)
- {
-- fprintf (stderr, i < prologueend ? ":bbb: remove push for %s\n" : ":bbb: remove pop for %s\n",
-+ log (i < prologueend ? "remove push for %s\n" : "remove pop for %s\n",
- reg_names[REGNO(reg)]);
- if (i < prologueend)
- adjust += 4;
-@@ -1574,7 +1581,7 @@ shrink_stack_frame (void)
- int add1 = i < prologueend || !usea5 ? 1 : 0;
- if ((int) regs.size () + add1 < XVECLEN(pattern, 0) || regs.size () <= 2)
- {
-- fprintf (stderr, ":bbb: shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1, regs.size ());
-+ log ("shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1, regs.size ());
- if (regs.size () <= 2)
- {
- for (unsigned k = 0; k < regs.size (); ++k)
-@@ -1667,7 +1674,7 @@ shrink_stack_frame (void)
- if (freemask & regbit)
- {
- adjust += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
-- fprintf (stderr, ":bbb: remove push for %s\n", reg_names[REGNO(src)]);
-+ log ("remove push for %s\n", reg_names[REGNO(src)]);
- SET_INSN_DELETED(insn);
- }
- }
-@@ -1678,7 +1685,7 @@ shrink_stack_frame (void)
- unsigned regbit = 1 << REGNO(dst);
- if (freemask & regbit)
- {
-- fprintf (stderr, ":bbb: remove pop for %s\n", reg_names[REGNO(dst)]);
-+ log ("remove pop for %s\n", reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
- }
- }
-@@ -1726,99 +1733,6 @@ shrink_stack_frame (void)
- return 0;
- }
+@@ -3255,11 +3259,15 @@ expand_asm_stmt (gasm *stmt)
+ if (reg_overlap_mentioned_p (clobbered_reg, output_rvec[k]))
+ internal_error ("asm clobber conflict with output operand");
--/*
-- * Always prefer lower register numbers within the class.
-- */
--static unsigned
--bb_reg_rename (void)
--{
-- for (unsigned index = 0; index < insns.size (); ++index)
-- {
-- insn_info & ii = infos[index];
-- const unsigned def = ii._def;
-- unsigned mask = ii.get_def_mask ();
--
-- if (!mask)
-- continue;
--
-- std::vector<unsigned> found;
-- std::vector<unsigned> todo;
-- if (index + 1 < insns.size ())
-- todo.push_back (index + 1);
--
-- found.push_back (index);
-- /* a register was defined, follow all branches. */
-- while (todo.size ())
-- {
-- unsigned pos = todo[todo.size () - 1];
-- todo.pop_back ();
--
-- if (LABEL_P(insns[pos]))
-- {
-- if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
-- continue;
-- }
--
-- insn_info & jj = infos[pos];
--
-- /* update free regs. */
-- mask &= ~jj._use;
-- mask &= ~jj._def;
-- if (!mask)
-- break;
--
-- /* defined again. */
-- if (jj._def & def)
-- continue;
--
-- /* not referenced. */
-- if (!(jj._use & def))
-- continue;
--
-- found.push_back (pos);
--
-- /* follow jump and/or next insn. */
-- rtx_insn * insn = insns[pos];
-- if (JUMP_P(insn))
-- {
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-- if (j != insn2index.end ())
-- todo.push_back (j->second);
--
-- rtx jmppattern = PATTERN (insn);
--
-- rtx jmpsrc = XEXP(jmppattern, 1);
-- if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-- if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
-- }
-- else if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
-- }
--
-- if (mask)
-- {
-- int oldregno = bit2regno (def);
-- int newregno = bit2regno (mask);
-- fprintf (stderr, ":bbb: bb_reg_rename %s -> %s (%d insns)\n", reg_names[oldregno], reg_names[newregno],
-- found.size ());
--
-- for (std::vector<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
-- {
-- debug_rtx (insns[*i]);
-- do_reg_rename (PATTERN (insns[*i]), oldregno, newregno);
-- }
--
-- cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
-- cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
-- return 1;
-- }
-- }
-- return 0;
--}
++/**
++ * SBF: Why?
++ */
++#ifndef TARGET_AMIGA
+ for (unsigned k = 0; k < ninputs - ninout; ++k)
+ if (reg_overlap_mentioned_p (clobbered_reg, input_rvec[k]))
+ internal_error ("asm clobber conflict with input operand");
++#endif
+ }
-
--extern const char * current_function_func_begin_label;
- extern class opt_pass * global_pass_regrename;
+ XVECEXP (body, 0, i++) = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
+ }
- namespace
-@@ -1848,10 +1762,10 @@ namespace
- virtual bool
- gate (function *)
- {
-- if (!flag_bbb_opts)
-- flag_bbb_opts = "*";
-+ if (!string_bbb_opts)
-+ string_bbb_opts = "+";
+diff --git a/gcc/collect2.c b/gcc/collect2.c
+index bffac802b8fe..f52a66ef1b58 100644
+--- gcc/collect2.c
++++ gcc/collect2.c
+@@ -1392,6 +1392,11 @@ main (int argc, char **argv)
+ add_to_list (&libs, s);
+ }
+ #endif
++ /* begin-GG-local: dynamic libraries */
++ #ifdef COLLECT2_LIBNAME_HOOK
++ COLLECT2_LIBNAME_HOOK(arg);
++ #endif
++ /* end-GG-local */
+ break;
-- return TARGET_AMIGA && optimize > 0 && flag_bbb_opts;
-+ return TARGET_AMIGA && optimize > 0 && string_bbb_opts && !strchr (string_bbb_opts, '-');
+ #ifdef COLLECT_EXPORT_LIST
+@@ -1492,6 +1497,11 @@ main (int argc, char **argv)
+ add_to_list (&libs, arg);
+ }
+ #endif
++ /* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_LIBNAME_HOOK
++ COLLECT2_LIBNAME_HOOK(arg);
++#endif
++ /* end-GG-local */
+ }
}
- virtual unsigned int
-@@ -1883,20 +1797,21 @@ namespace
- df_note_add_problem ();
- df_analyze ();
-
-- update_insns ();
-+ be_verbose = strchr (string_bbb_opts, 'v');
-
-- bool do_opt_strcpy = strchr (flag_bbb_opts, 's') || strchr (flag_bbb_opts, '*');
-- bool do_commute_add_move = strchr (flag_bbb_opts, 'a') || strchr (flag_bbb_opts, '*');
-- bool do_propagate_moves = strchr (flag_bbb_opts, 'p') || strchr (flag_bbb_opts, '*');
-- bool do_const_cmp_to_sub = strchr (flag_bbb_opts, 'c') || strchr (flag_bbb_opts, '*');
-- bool do_merge_add = strchr (flag_bbb_opts, 'm') || strchr (flag_bbb_opts, '*');
-- bool do_elim_dead_assign = strchr (flag_bbb_opts, 'e') || strchr (flag_bbb_opts, '*');
-- bool do_bb_reg_rename = strchr (flag_bbb_opts, 'r') || strchr (flag_bbb_opts, '*');
-- bool do_shrink_stack_frame = strchr (flag_bbb_opts, 'f') || strchr (flag_bbb_opts, '*');
-+ bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
-+ bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-+ bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr (string_bbb_opts, '+');
-+ bool do_const_cmp_to_sub = strchr (string_bbb_opts, 'c') || strchr (string_bbb_opts, '+');
-+ bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr (string_bbb_opts, '+');
-+ bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr (string_bbb_opts, '+');
-+ bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
-+ bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
-
- for (;;)
- {
- int done = 1;
-+ update_insns ();
- if (do_opt_strcpy && opt_strcpy ())
- done = 0, update_insns ();
-
-@@ -1916,20 +1831,20 @@ namespace
- if (do_elim_dead_assign && elim_dead_assign ())
- done = 0, update_insns ();
-
-- if (done)
-- break;
-- }
-+ if (do_bb_reg_rename && ::global_pass_regrename)
-+ {
-+ class opt_pass * rr = ::global_pass_regrename->clone ();
-+ rr->execute (0);
-
-- if (do_bb_reg_rename && ::global_pass_regrename)
-- {
-- class opt_pass * rr = ::global_pass_regrename->clone ();
-- rr->execute (0);
-+ // update_insns ();
-+ // update_insn_infos ();
-+ // bb_reg_rename ();
-
--// update_insns ();
--// update_insn_infos ();
--// bb_reg_rename ();
-+ update_insns ();
-+ }
+@@ -1608,6 +1618,11 @@ main (int argc, char **argv)
-- update_insns ();
-+ if (done)
-+ break;
- }
+ fprintf (stderr, "\n");
+ }
++ /* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_PRELINK_HOOK
++ COLLECT2_PRELINK_HOOK(ld1_argv, &strip_flag);
++#endif
++ /* end-GG-local */
- if (do_shrink_stack_frame)
-@@ -1938,8 +1853,8 @@ namespace
- update_insns ();
+ /* Load the program, searching all libraries and attempting to provide
+ undefined symbols from repository information.
+@@ -1648,6 +1663,8 @@ main (int argc, char **argv)
}
+ }
-- if (strchr (flag_bbb_opts, 'X') || strchr (flag_bbb_opts, 'x'))
-- dump_insns ("bbb 1", strchr (flag_bbb_opts, 'X'));
-+ if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
-+ dump_insns ("bbb", strchr (string_bbb_opts, 'X'));
- clear ();
-
- return 0;
-diff --git a/gcc/final.c b/gcc/final.c
-index 9d21ffc1baff..31f9b4815d75 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -2165,7 +2165,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
++ /* begin-GG-local: dynamic libraries */
++#ifndef COLLECT2_POSTLINK_HOOK
+ /* Unless we have done it all already, examine the namelist and search for
+ static constructors and destructors to call. Write the constructor and
+ destructor tables to a .s file and reload. */
+@@ -1674,6 +1691,10 @@ main (int argc, char **argv)
+ frame_tables.number),
+ frame_tables.number);
+ }
++#else /* COLLECT2_POSTLINK_HOOK */
++ COLLECT2_POSTLINK_HOOK(output_file);
++#endif
++/* end-GG-local */
- /* Ignore deleted insns. These can occur when we split insns (due to a
- template of "#") while not optimizing. */
-- if (insn->deleted () || GET_CODE(insn) == VALUE || GET_CODE(insn) == CONST_FIXED)
-+ if (insn->deleted () || GET_CODE(insn) == VALUE || GET_CODE(insn) == CONST_FIXED || GET_CODE(insn) == DEBUG_IMPLICIT_PTR)
- return NEXT_INSN (insn);
+ /* If the scan exposed nothing of special interest, there's no need to
+ generate the glue code and relink so return now. */
+@@ -1716,6 +1737,11 @@ main (int argc, char **argv)
- switch (GET_CODE (insn))
-diff --git a/gcc/passes.def b/gcc/passes.def
-index 5b78cbd7fb38..f48fd2581cba 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -447,6 +447,9 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_ree);
- NEXT_PASS (pass_compare_elim_after_reload);
- NEXT_PASS (pass_branch_target_load_optimize1);
-+ NEXT_PASS (pass_thread_prologue_and_epilogue);
-+ NEXT_PASS (pass_rtl_dse2);
-+ NEXT_PASS (pass_stack_adjustments);
- NEXT_PASS (pass_jump2);
- NEXT_PASS (pass_duplicate_computed_gotos);
- NEXT_PASS (pass_sched_fusion);
-@@ -454,9 +457,6 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_if_after_reload);
- NEXT_PASS (pass_regrename);
- NEXT_PASS (pass_cprop_hardreg);
-- NEXT_PASS (pass_thread_prologue_and_epilogue);
-- NEXT_PASS (pass_rtl_dse2);
-- NEXT_PASS (pass_stack_adjustments);
- NEXT_PASS (pass_fast_rtl_dce);
- NEXT_PASS (pass_reorder_blocks);
- NEXT_PASS (pass_bbb_optimizations);
-
-From 7c3f103835a555944b28e4e2a0726f33830abc6a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 14 Apr 2017 18:35:14 +0200
-Subject: [PATCH 068/303] @N add eclipse project files
-
----
- .cproject | 180 +++++++++++++++++++++++++++++
- .project | 16 +++
- .settings/language.settings.xml | 25 ++++
- .settings/org.eclipse.cdt.codan.core.prefs | 71 ++++++++++++
- .settings/org.eclipse.cdt.core.prefs | 6 +
- .settings/org.eclipse.core.runtime.prefs | 5 +
- 6 files changed, 303 insertions(+)
- create mode 100755 .cproject
- create mode 100755 .settings/language.settings.xml
- create mode 100755 .settings/org.eclipse.cdt.codan.core.prefs
- create mode 100755 .settings/org.eclipse.cdt.core.prefs
- create mode 100755 .settings/org.eclipse.core.runtime.prefs
-
-diff --git a/.cproject b/.cproject
-new file mode 100755
-index 000000000000..62b1c0f38dcb
---- /dev/null
-+++ .cproject
-@@ -0,0 +1,180 @@
-+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-+ <storageModule moduleId="org.eclipse.cdt.core.settings">
-+ <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522">
-+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522" moduleId="org.eclipse.cdt.core.settings" name="Debug">
-+ <externalSettings/>
-+ <extensions>
-+ <extension id="org.eclipse.cdt.core.Cygwin_PE" point="org.eclipse.cdt.core.BinaryParser"/>
-+ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ </extensions>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug">
-+ <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522." name="/" resourcePath="">
-+ <toolChain id="cdt.managedbuild.toolchain.gnu.cygwin.base.2053847551" name="Cygwin GCC" superClass="cdt.managedbuild.toolchain.gnu.cygwin.base">
-+ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.Cygwin_PE" id="cdt.managedbuild.target.gnu.platform.cygwin.base.2091243283" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.cygwin.base"/>
-+ <builder buildPath="${workspace_loc:/debugwin}/Debug" id="cdt.managedbuild.target.gnu.builder.cygwin.base.1660320342" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.cygwin.base">
-+ <outputEntries>
-+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
-+ </outputEntries>
-+ </builder>
-+ <tool id="cdt.managedbuild.tool.gnu.assembler.cygwin.base.607722454" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.cygwin.base">
-+ <option id="gnu.both.asm.option.include.paths.2094451885" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
-+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/amigaos-cross-toolchain/.build-m68k/build/gcc-6/gcc}&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
-+ </option>
-+ <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1425989952" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.archiver.cygwin.base.2119049474" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.cygwin.base"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968" name="Cygwin C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base">
-+ <option id="gnu.cpp.compiler.option.include.paths.466783605" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/gcc-6/libcpp/include}&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc&quot;"/>
-+ </option>
-+ <option id="gnu.cpp.compiler.option.optimization.level.193715843" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.debugging.level.2136883244" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.preprocessor.def.807277038" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ </option>
-+ <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604" name="Cygwin C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base">
-+ <option id="gnu.c.compiler.option.include.paths.692774379" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/gcc-6/libcpp/include}&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc&quot;"/>
-+ </option>
-+ <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.227992926" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.debugging.level.748883400" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.preprocessor.def.symbols.1982594045" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ </option>
-+ <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313" superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.c.linker.cygwin.base.344641511" name="Cygwin C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.cygwin.base"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base.968200320" name="Cygwin C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base">
-+ <option id="gnu.cpp.link.option.libs.260033787" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"/>
-+ <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1537937183" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-+ <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-+ <additionalInput kind="additionalinput" paths="$(LIBS)"/>
-+ </inputType>
-+ </tool>
-+ </toolChain>
-+ </folderInfo>
-+ <sourceEntries>
-+ <entry excluding="ada/|doc/|fortran/|ginclude/|go/|java/|jit/|lto/|objc/|objcp/|po/|testsuite/|config/aarch64/|config/alpha/|config/arc/|config/arm/|config/avr/|config/bfin/|config/c6x/|config/cr16/|config/cris/|config/epiphany/|config/fr30/|config/frv/|config/ft32/|config/h8300/|config/i386/|config/ia64/|config/iq2000/|config/lm32/|config/m32c/|config/m32r/|config/mcore/|config/mep/|config/microblaze/|config/mips/|config/mmix/|config/mn10300/|config/moxie/|config/msp430/|config/nds32/|config/nios2/|config/nvptx/|config/pa/|config/pdp11/|config/rl78/|config/rs6000/|config/rx/|config/s390/|config/sh/|config/sparc/|config/spu/|config/stormy16/|config/tilegx/|config/tilepro/|config/v850/|config/vax/|config/visium/|config/vms/|config/xtensa/" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="gcc"/>
-+ </sourceEntries>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-+ </cconfiguration>
-+ <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.811454954">
-+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.811454954" moduleId="org.eclipse.cdt.core.settings" name="Release">
-+ <externalSettings/>
-+ <extensions>
-+ <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-+ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-+ </extensions>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.811454954" name="Release" parent="cdt.managedbuild.config.gnu.cross.exe.release">
-+ <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.811454954." name="/" resourcePath="">
-+ <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.101222491" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
-+ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1798723854" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
-+ <builder buildPath="${workspace_loc:/debugwin}/Release" id="cdt.managedbuild.builder.gnu.cross.507087034" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
-+ <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.1686563067" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.debugging.level.60172226" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.include.paths.696908692" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
-+ </option>
-+ <option id="gnu.c.compiler.option.preprocessor.def.symbols.652362073" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ </option>
-+ <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1150724656" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
-+ <option id="gnu.cpp.compiler.option.optimization.level.2088586809" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.debugging.level.1993778911" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.include.paths.1936413739" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
-+ </option>
-+ <option id="gnu.cpp.compiler.option.preprocessor.def.625117841" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ </option>
-+ <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.946489608" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.738916918" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
-+ <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1880308865" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-+ <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-+ <additionalInput kind="additionalinput" paths="$(LIBS)"/>
-+ </inputType>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1813524686" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.assembler.1395544547" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
-+ <option id="gnu.both.asm.option.include.paths.1443815690" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
-+ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
-+ </option>
-+ <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1421786104" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-+ </tool>
-+ </toolChain>
-+ </folderInfo>
-+ <sourceEntries>
-+ <entry excluding="src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
-+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
-+ </sourceEntries>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-+ </cconfiguration>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <project id="debugwin.cdt.managedbuild.target.gnu.cross.exe.1884740625" name="Executable" projectType="cdt.managedbuild.target.gnu.cross.exe"/>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-+ <storageModule moduleId="refreshScope" versionNumber="2">
-+ <configuration configurationName="Debug">
-+ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
-+ </configuration>
-+ <configuration configurationName="Release">
-+ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-+ <storageModule moduleId="scannerConfiguration">
-+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466;cdt.managedbuild.tool.gnu.c.compiler.input.1150724656">
-+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.c.compiler.502147450;cdt.managedbuild.tool.gnu.c.compiler.input.1173428818">
-+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968;cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803">
-+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604;cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313">
-+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.216739552;cdt.managedbuild.tool.gnu.cpp.compiler.input.1269341019">
-+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749;cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092">
-+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ </storageModule>
-+</cproject>
-diff --git a/.project b/.project
-index ab5c4b198d08..22b8c5a11f48 100644
---- .project
-+++ .project
-@@ -5,7 +5,23 @@
- <projects>
- </projects>
- <buildSpec>
-+ <buildCommand>
-+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-+ <triggers>clean,full,incremental,</triggers>
-+ <arguments>
-+ </arguments>
-+ </buildCommand>
-+ <buildCommand>
-+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-+ <triggers>full,incremental,</triggers>
-+ <arguments>
-+ </arguments>
-+ </buildCommand>
- </buildSpec>
- <natures>
-+ <nature>org.eclipse.cdt.core.cnature</nature>
-+ <nature>org.eclipse.cdt.core.ccnature</nature>
-+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
- </natures>
- </projectDescription>
-diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
-new file mode 100755
-index 000000000000..c6ac9211311a
---- /dev/null
-+++ .settings/language.settings.xml
-@@ -0,0 +1,25 @@
-+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-+<project>
-+ <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522" name="Debug">
-+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
-+ <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
-+ <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
-+ <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
-+ <provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorCygwin" console="false" env-hash="1253352314297216180" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorCygwin" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cygwin" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
-+ <language-scope id="org.eclipse.cdt.core.gcc"/>
-+ <language-scope id="org.eclipse.cdt.core.g++"/>
-+ </provider>
-+ </extension>
-+ </configuration>
-+ <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.811454954" name="Release">
-+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
-+ <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
-+ <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
-+ <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
-+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="860895942062206931" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
-+ <language-scope id="org.eclipse.cdt.core.gcc"/>
-+ <language-scope id="org.eclipse.cdt.core.g++"/>
-+ </provider>
-+ </extension>
-+ </configuration>
-+</project>
-diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs
-new file mode 100755
-index 000000000000..b5248c620107
---- /dev/null
-+++ .settings/org.eclipse.cdt.codan.core.prefs
-@@ -0,0 +1,71 @@
-+eclipse.preferences.version=1
-+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
-+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
-+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
-+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
-+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
-+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
-+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
-+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
-+org.eclipse.cdt.codan.checkers.noreturn=Error
-+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
-+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
-+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
-+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
-+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
-+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
-+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
-+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
-+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
-+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
-+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
-+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
-+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
-+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
-+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
-+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
-+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
-+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
-+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
-+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
-+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
-+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
-+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
-+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
-+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
-diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
-new file mode 100755
-index 000000000000..8ec9fe72ca59
---- /dev/null
-+++ .settings/org.eclipse.cdt.core.prefs
-@@ -0,0 +1,6 @@
-+eclipse.preferences.version=1
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/delimiter=;
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/operation=replace
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/value=C\:\\WINDOWS\\system32;C\:\\WINDOWS;C\:\\Program Files\\SlikSvn\\bin;C\:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0;c\:\\cygwin\\bin;D\:\\develop\\workspaces\\c1\\amigaos-cross-toolchain\\m68k-amigaos\\bin
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/append=true
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/appendContributed=true
-diff --git a/.settings/org.eclipse.core.runtime.prefs b/.settings/org.eclipse.core.runtime.prefs
-new file mode 100755
-index 000000000000..12511e62a174
---- /dev/null
-+++ .settings/org.eclipse.core.runtime.prefs
-@@ -0,0 +1,5 @@
-+content-types/enabled=true
-+content-types/org.eclipse.cdt.core.cHeader/file-extensions=def
-+content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=h
-+content-types/org.eclipse.cdt.core.cxxSource/file-extensions=c
-+eclipse.preferences.version=1
-
-From 4920a3ed01948bcc777d84e3c42f4e92310ee499 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 19 Apr 2017 13:38:11 +0200
-Subject: [PATCH 069/303] @R be nice to other windows programs and replace
- /cygdrive/x/ with x:/ -> include/lib path discovery is now working in Eclipse
- running on Windows
-
----
- gcc/gcc.c | 8 ++++----
- libiberty/lrealpath.c | 18 +++++++++++++++++-
- 2 files changed, 21 insertions(+), 5 deletions(-)
-
-diff --git a/gcc/gcc.c b/gcc/gcc.c
-index 33ca41545736..2974b91300ca 100644
---- gcc/gcc.c
-+++ gcc/gcc.c
-@@ -10109,7 +10109,7 @@ const char * amiga_m68k_prefix_func(int argc, const char ** argv) {
- char * p = 0;
- if (standard_libexec_prefix)
- {
-- char * glp = concat(standard_libexec_prefix, "",0);
-+ char * glp = concat(standard_libexec_prefix, "", NULL);
- p = strrchr(glp, '/');
- if (p)
- {
-@@ -10122,17 +10122,17 @@ const char * amiga_m68k_prefix_func(int argc, const char ** argv) {
- if (p)
- {
- p[1] = 0;
-- p = concat(glp, "m68k-amigaos/", 0);
-+ p = concat(glp, "m68k-amigaos/", NULL);
- }
- }
- }
- free(glp);
+ 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;
}
- if (!p)
-- p = concat("../../../../", "", 0);
-+ p = concat("../../../../", "", NULL);
- for (int i = 0; i < argc; ++i) {
-- char * q = concat(p, argv[i], 0);
-+ char * q = concat(p, argv[i], NULL);
- free(p);
- p = q;
- }
-diff --git a/libiberty/lrealpath.c b/libiberty/lrealpath.c
-index b27c8de990e9..78c06e46da58 100644
---- libiberty/lrealpath.c
-+++ libiberty/lrealpath.c
-@@ -73,7 +73,7 @@ extern char *canonicalize_file_name (const char *);
+@@ -1821,6 +1847,11 @@ main (int argc, char **argv)
+ maybe_unlink (export_file);
#endif
- char *
--lrealpath (const char *filename)
-+__xlrealpath (const char *filename)
- {
- /* Method 1: The system has a compile time upper bound on a filename
- path. Use that and realpath() to canonicalize the name. This is
-@@ -155,3 +155,19 @@ lrealpath (const char *filename)
- /* This system is a lost cause, just duplicate the filename. */
- return strdup (filename);
- }
-+
-+
-+char *
-+lrealpath (const char *filename)
-+{
-+ char * r = __xlrealpath(filename);
-+#if defined (_WIN32)
-+ if (strncmp(r, "/cygdrive/", 10) == 0)
-+ {
-+ r[9] = r[10];
-+ r[10] = ':';
-+ r = strdup(&r[9]);
-+ }
++ /* begin-GG-local: dynamic libraries */
++#ifdef COLLECT2_EXTRA_CLEANUP
++ COLLECT2_EXTRA_CLEANUP();
+#endif
-+ return r;
-+}
-
-From f6379a10611d6376109a63b65768387905a30490 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 19 Apr 2017 13:41:44 +0200
-Subject: [PATCH 070/303] @B fix rename-registers if using register parameters:
- add clobbers for the regs
-
----
- gcc/config/m68k/amigaos.c | 1671 +++++++++++++++++++++++----------------------
- gcc/config/m68k/m68k.c | 6 +
- 2 files changed, 842 insertions(+), 835 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 88205e25476e..ca8eea305345 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -1,835 +1,836 @@
--/* 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
--#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 "attribs.h"
--#include "flags.h"
--#include "expr.h"
--#include "toplev.h"
--#include "tm_p.h"
--#include "target.h"
--#include "diagnostic-core.h"
--#include "config/m68k/amigaos.h"
--
--//#define MYDEBUG 1
--#ifdef MYDEBUG
--#define DPRINTF(x) printf x; fflush(stdout);
--#else
--#define DPRINTF(x)
--#endif
--
--//int amiga_declare_object;
--
--#if 0
--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 ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED,
-- 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_ELT(TYPE_SIZE (type), 1) == 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 ((MEM_READONLY_P (rtl) && !MEM_VOLATILE_P (rtl)
-- && (flag_pic<3 || (TREE_CODE (decl) == STRING_CST
-- )
-- || amigaos_put_in_text (decl)))
-- || (TREE_CODE (decl) == VAR_DECL
-- && DECL_SECTION_NAME (decl) != NULL))
-- 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 (OPT_Wattributes, "`%s' attribute only applies to variables",
-- IDENTIFIER_POINTER (name));
-- *no_add_attrs = true;
-- }
--
-- return NULL_TREE;
--}
--
--//----- from 68k.c start
--
--
--
--
--
--
--/* 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);
--//}
--#endif
--
--/*
-- * begin-GG-local: explicit register specification for parameters.
-- *
-- * Reworked and ported to gcc-6.2.0 by Stefan "Bebbo" Franke.
-- */
--
--/**
-- * Define this here and add it to tm_p -> all know the custom type and allocate/use the correct size.
-- */
--struct amigaos_args
--{
-- int num_of_regs;
-- long regs_already_used;
-- int last_arg_reg;
-- int last_arg_len;
-- tree formal_type; /* New field: formal type of the current argument. */
--};
--
--static struct amigaos_args mycum;
--static CUMULATIVE_ARGS * lastcum;
--
--/* 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
--amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
--{
-- struct amigaos_args * cum = &mycum;
-- lastcum = cump;
-- cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
-- DPRINTF(("0amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
--
-- /* 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. */
--
-- cum->last_arg_reg = -1;
-- cum->regs_already_used = 0;
--
-- if (decl)
-- {
-- tree attrs = DECL_ATTRIBUTES(decl);
-- if (lookup_attribute ("stkparm", attrs))
-- cum->num_of_regs = 0;
-- else
-- {
-- tree ratree = lookup_attribute ("regparm", attrs);
-- cum->num_of_regs = amigaos_regparm != 0 ?
-- amigaos_regparm : AMIGAOS_DEFAULT_REGPARM;
-- if (ratree)
-- {
-- tree args = TREE_VALUE(ratree);
--
-- if (args && TREE_CODE (args) == TREE_LIST)
-- {
-- tree val = TREE_VALUE(args);
-- if (TREE_CODE (val) == INTEGER_CST)
-- {
-- int no = TREE_INT_CST_LOW(val);
-- if (no > 0 && no < AMIGAOS_MAX_REGPARM)
-- cum->num_of_regs = no;
-- }
-- }
-- }
-- }
-- }
-- 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
--
-- if (fntype)
-- cum->formal_type = TYPE_ARG_TYPES(fntype);
-- else
-- /* Call to compiler-support function. */
-- cum->formal_type = 0;
-- DPRINTF(("1amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
--}
--
--/* Update the data in CUM to advance over an argument. */
--
--void
--amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree,
-- bool)
--{
-- struct amigaos_args * cum = &mycum;
-- CUMULATIVE_ARGS *cump = (CUMULATIVE_ARGS *) get_cumulative_args (cum_v);
-- /* Update the data in CUM to advance over an argument. */
--
-- DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cump));
-- if (cump != lastcum)
-- return;
--
-- 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;
-- }
--
-- if (cum->formal_type)
-- cum->formal_type = TREE_CHAIN(cum->formal_type);
--}
--
--/* 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. */
--
--static struct rtx_def *
--_m68k_function_arg (CUMULATIVE_ARGS *, machine_mode, const_tree);
--
--static struct rtx_def *
--_m68k_function_arg (CUMULATIVE_ARGS *cump, machine_mode mode, const_tree type)
--{
-- struct amigaos_args * cum = &mycum;
-- DPRINTF(("m68k_function_arg numOfRegs=%d\r\n", cum ? cum->num_of_regs : 0));
--
-- if (cump != lastcum)
-- return 0;
--
-- 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 (!type || 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 == AMIGAOS_MAX_REGPARM && altregbegin != -1)
-- {
-- DPRINTF(("look for alt reg\n"));
-- regbegin = altregbegin;
-- altregbegin = -1;
-- goto look_for_reg;
-- }
-- }
--
-- if (cum->last_arg_reg != -1)
-- {
-- DPRINTF(("-> gen_rtx_REG %d\r\n", cum->last_arg_reg));
-- return gen_rtx_REG (mode, cum->last_arg_reg);
-- }
-- }
-- return 0;
--}
--
--/* 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_t cum_v, machine_mode mode,
-- const_tree type, bool)
--{
-- struct amigaos_args * cum = &mycum;
--
-- DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p));
--
-- CUMULATIVE_ARGS *cump = (CUMULATIVE_ARGS *) get_cumulative_args (cum_v);
--
-- if (cump != lastcum)
-- return 0;
--
-- tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
-- if (asmtree && 0 == strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-- {
-- int i;
-- cum->last_arg_reg = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-- 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);
-- }
-- return _m68k_function_arg (cump, 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 (const_tree type1, const_tree type2)
--{
-- DPRINTF(("amigaos_comp_type_attributes\n"));
-- /* 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))
-- {
-- tree attr1 = TYPE_ATTRIBUTES(arg1);
-- tree attr2 = TYPE_ATTRIBUTES(arg2);
-- if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr1))))
-- attr1 = NULL_TREE;
-- if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr2))))
-- attr2 = NULL_TREE;
-- if (attr1 && attr2)
-- {
-- if (TREE_FIXED_CST_PTR(TREE_VALUE(attr1))->data.low
-- != TREE_FIXED_CST_PTR(TREE_VALUE(attr2))->data.low)
-- return 0;
-- }
-- else if (attr1 || attr2)
-- return 0; /* asm attribute only on one side. */
-- }
-- if (arg1 || arg2)
-- return 0; /* different count of parameters. */
-- }
-- return 1;
--}
--
--/* 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). */
--#if 0
--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
--}
--#endif
--
--/* end-GG-local */
--
--
--/* Handle a "regparm", "stkparm" attribute;
-- arguments as in struct attribute_spec.handler. */
--tree
--amigaos_handle_type_attribute (tree *node, tree name, tree args,
-- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
--{
-- tree nnn = *node;
-- do { // while (0);
-- DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
-- if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE
-- || TREE_CODE (nnn) == 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))
-- {
-- DPRINTF(("regparm found\n"));
--
-- if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
-- {
-- error ("`regparm' and `stkparm' are mutually exclusive");
-- break;
-- }
-- if (args && TREE_CODE (args) == TREE_LIST)
-- {
-- tree val = TREE_VALUE(args);
-- DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
-- if (TREE_CODE (val) == INTEGER_CST)
-- {
-- int no = TREE_INT_CST_LOW(val);
-- if (no < 0 || no > AMIGAOS_MAX_REGPARM)
-- {
-- error ("`regparm' attribute: value %d not in [0 - %d]",
-- no,
-- AMIGAOS_MAX_REGPARM);
-- break;
-- }
-- }
-- else
-- {
-- error ("invalid argument(s) to `regparm' attribute");
-- break;
-- }
-- }
-- }
-- else if (is_attribute_p ("stkparm", name))
-- {
-- if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
-- {
-- error ("`regparm' and `stkparm' are mutually exclusive");
-- break;
-- }
-- }
-- else if (is_attribute_p ("stackext", name))
-- {
-- if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
-- {
-- error ("`stackext' and `interrupt' are mutually exclusive");
-- break;
-- }
-- }
-- else if (is_attribute_p ("saveds", name))
-- {
-- }
-- }
-- else
-- {
-- warning (OPT_Wattributes, "`%s' attribute only applies to functions",
-- IDENTIFIER_POINTER(name));
-- }
-- return NULL_TREE;
-- } while (0);
-- // error case
-- *no_add_attrs = true;
-- return NULL_TREE;
--}
--
--
--extern bool
--m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
--
--bool
--amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
-- int *total, bool speed)
--{
--// DPRINTF(("outer: %d, opno: %d", outer_code, opno));
-- bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
--// *total *= 4;
--// fprintf(stderr, "costs: %d, mode=%d, outer=%d, opno=%d, speed=%d, ok=%d\n", *total * 4, mode, outer_code, opno, speed, r);
--// debug_rtx(x);
-- return r;
--}
--
--
--/* Output assembly to switch to section NAME with attribute FLAGS. */
--
--extern void
--amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
--{
-- if (0 == strncmp(".text", name, 5))
-- name = ".text";
-- fprintf (asm_out_file, "\t%s\n", name);
--}
--
--/* Baserel support. */
--
--/**
-- * Does x reference the pic_reg and is const or plus?
-- */
--int amiga_is_const_pic_ref(const_rtx x)
--{
-- const_rtx y = x;
-- if (flag_pic < 3)
-- return false;
-- while (GET_CODE(y) == CONST || GET_CODE(y) == PLUS)
-- y = XEXP(y, 0);
-- return (x != y && REG_P(y) && REGNO(y) == PIC_REG);
--}
--
--
--/* 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;
--}
--
--reg_class_t
--amiga_preferred_rename_class2(reg_class_t rclass ATTRIBUTE_UNUSED, int regno )
--{
-- if (regno == 0)
-- return D0_REGS;
-- if (regno == 8)
-- return A0_REGS;
-- return regno_reg_class[regno];
--}
++ /* end-GG-local */
+ return 0;
+ }
+
+diff --git a/gcc/config.gcc b/gcc/config.gcc
+index bf3f32da08ac..7aa190620911 100644
+--- gcc/config.gcc
++++ gcc/config.gcc
+@@ -1940,6 +1940,27 @@ m68k-*-elf* | fido-*-elf*)
+ ;;
+ esac
+ ;;
++m68k*-*-amigaosvasm*)
++ default_m68k_cpu=68000
++ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
++ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_AMIGAOS_VASM TARGET_CPU_DEFAULT=0"
++ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
++ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
++ extra_objs=amigaos.o
++ extra_options="${extra_options} m68k/amigaos.opt"
++ gnu_ld=yes
++ ;;
++m68k*-*-amigaos*)
++ default_m68k_cpu=68000
++ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
++ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_CPU_DEFAULT=0"
++ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
++ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
++ extra_objs=amigaos.o
++ extra_options="${extra_options} m68k/amigaos.opt"
++ gnu_ld=yes
++ CFLAGS="-Os"
++ ;;
+ m68k*-*-netbsdelf*)
+ default_m68k_cpu=68020
+ default_cf_cpu=5475
+diff --git a/gcc/config/m68k/amigaos-protos.h b/gcc/config/m68k/amigaos-protos.h
+new file mode 100644
+index 000000000000..e5cd6e950b52
+--- /dev/null
++++ gcc/config/m68k/amigaos-protos.h
+@@ -0,0 +1,55 @@
+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
+ Free Software Foundation, Inc.
@@ -14673,6 +5912,67 @@ index 88205e25476e..ca8eea305345 100644
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
++#undef TARGET_AMIGAOS
++#define TARGET_AMIGAOS 1
++
++extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree, tree);
++
++/* 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), (INDIRECT)))
++
++#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_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 *);
++#endif
+diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
+new file mode 100644
+index 000000000000..28d20a980978
+--- /dev/null
++++ gcc/config/m68k/amigaos.c
+@@ -0,0 +1,931 @@
++/* 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
+#define REGPARMS_68K 1
+
@@ -14690,6 +5990,8 @@ index 88205e25476e..ca8eea305345 100644
+#include "tm_p.h"
+#include "target.h"
+#include "diagnostic-core.h"
++#include "langhooks.h"
++#include "function.h"
+#include "config/m68k/amigaos.h"
+
+//#define MYDEBUG 1
@@ -14702,249 +6004,30 @@ index 88205e25476e..ca8eea305345 100644
+//int amiga_declare_object;
+
+#if 0
-+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 ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED,
-+ 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_ELT(TYPE_SIZE (type), 1) == 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 ((MEM_READONLY_P (rtl) && !MEM_VOLATILE_P (rtl)
-+ && (flag_pic<3 || (TREE_CODE (decl) == STRING_CST
-+ )
-+ || amigaos_put_in_text (decl)))
-+ || (TREE_CODE (decl) == VAR_DECL
-+ && DECL_SECTION_NAME (decl) != NULL))
-+ 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 (OPT_Wattributes, "`%s' attribute only applies to variables",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-+
-+ return NULL_TREE;
-+}
+
+//----- from 68k.c start
+
-+
-+
-+
-+
-+
+/* Stack checking and automatic extension support. */
+
+void
+amigaos_prologue_begin_hook (FILE *stream, int fsize)
-+{
-+ if (TARGET_STACKCHECK)
-+ {
-+ if (fsize < 256)
++ {
++ 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
++ "\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);
-+}
++ 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)
@@ -15035,9 +6118,10 @@ index 88205e25476e..ca8eea305345 100644
+amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
+{
+ struct amigaos_args * cum = decl == current_function_decl ? &mycum : &othercum;
-+ *cump = (int)cum;
++ *cump = decl == current_function_decl;
+ cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
-+ DPRINTF(("0amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
++ DPRINTF(
++ ("0amigaos_init_cumulative_args %s %p -> %d\r\n", decl ? lang_hooks.decl_printable_name (decl, 2) : "?", cum, cum->num_of_regs));
+
+ /* Initialize a variable CUM of type CUMULATIVE_ARGS
+ for a call to a function whose data type is FNTYPE.
@@ -15046,28 +6130,32 @@ index 88205e25476e..ca8eea305345 100644
+ cum->last_arg_reg = -1;
+ cum->regs_already_used = 0;
+
-+ if (decl)
++ if (fntype)
+ {
-+ tree attrs = DECL_ATTRIBUTES(decl);
-+ if (lookup_attribute ("stkparm", attrs))
-+ cum->num_of_regs = 0;
-+ else
++ tree attrs = TYPE_ATTRIBUTES(fntype);
++ if (attrs)
+ {
-+ tree ratree = lookup_attribute ("regparm", attrs);
-+ cum->num_of_regs = amigaos_regparm != 0 ?
-+ amigaos_regparm : AMIGAOS_DEFAULT_REGPARM;
-+ if (ratree)
++ if (lookup_attribute ("stkparm", attrs))
++ cum->num_of_regs = 0;
++ else
+ {
-+ tree args = TREE_VALUE(ratree);
-+
-+ if (args && TREE_CODE (args) == TREE_LIST)
++ tree ratree = lookup_attribute ("regparm", attrs);
++ cum->num_of_regs = amigaos_regparm != 0 ?
++ amigaos_regparm :
++ AMIGAOS_DEFAULT_REGPARM;
++ if (ratree)
+ {
-+ tree val = TREE_VALUE(args);
-+ if (TREE_CODE (val) == INTEGER_CST)
++ tree args = TREE_VALUE(ratree);
++
++ if (args && TREE_CODE (args) == TREE_LIST)
+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no > 0 && no < AMIGAOS_MAX_REGPARM)
-+ cum->num_of_regs = no;
++ tree val = TREE_VALUE(args);
++ if (TREE_CODE (val) == INTEGER_CST)
++ {
++ int no = TREE_INT_CST_LOW(val);
++ if (no > 0 && no < AMIGAOS_MAX_REGPARM)
++ cum->num_of_regs = no;
++ }
+ }
+ }
+ }
@@ -15089,13 +6177,20 @@ index 88205e25476e..ca8eea305345 100644
+ }
+ }
+
-+ //#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
++#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
++
++ if (fntype && DECL_STATIC_CHAIN(fntype))
++ {
++ rtx reg = amigaos_static_chain_rtx (decl, 0);
++ if (reg)
++ cum->regs_already_used |= (1 << REGNO(reg));
++ }
+
+ if (fntype)
+ cum->formal_type = TYPE_ARG_TYPES(fntype);
@@ -15105,16 +6200,21 @@ index 88205e25476e..ca8eea305345 100644
+ DPRINTF(("1amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
+}
+
++int
++amigaos_function_arg_reg (unsigned regno)
++{
++ return (mycum.regs_already_used & (1 << regno)) != 0;
++}
++
+/* Update the data in CUM to advance over an argument. */
+
+void
-+amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree,
-+ bool)
++amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree, bool)
+{
-+ struct amigaos_args *cum = *(struct amigaos_args **) get_cumulative_args (cum_v);
++ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
+ /* Update the data in CUM to advance over an argument. */
+
-+ DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cump));
++ DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cum));
+
+ if (cum->last_arg_reg != -1)
+ {
@@ -15140,9 +6240,6 @@ index 88205e25476e..ca8eea305345 100644
+ the preceding args and about the function being called. */
+
+static struct rtx_def *
-+_m68k_function_arg (CUMULATIVE_ARGS *, machine_mode, const_tree);
-+
-+static struct rtx_def *
+_m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree type)
+{
+ DPRINTF(("m68k_function_arg numOfRegs=%d\r\n", cum ? cum->num_of_regs : 0));
@@ -15153,8 +6250,7 @@ index 88205e25476e..ca8eea305345 100644
+
+ /* 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))
++ GET_MODE_UNIT_SIZE (mode) <= 12 && (GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT || mode == SCmode))
+ {
+ regbegin = 16; /* FPx */
+ len = GET_MODE_NUNITS(mode);
@@ -15180,8 +6276,7 @@ index 88205e25476e..ca8eea305345 100644
+ if (!(cum->regs_already_used & mask))
+ {
+ int end;
-+ for (end = reg; end < cum->num_of_regs && end < reg + len;
-+ end++, mask <<= 1)
++ 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)
@@ -15192,7 +6287,7 @@ index 88205e25476e..ca8eea305345 100644
+ }
+ }
+
-+ if (reg == AMIGAOS_MAX_REGPARM && altregbegin != -1)
++ if (reg == cum->num_of_regs && altregbegin != -1)
+ {
+ DPRINTF(("look for alt reg\n"));
+ regbegin = altregbegin;
@@ -15214,14 +6309,15 @@ index 88205e25476e..ca8eea305345 100644
+ in a register, and which register. */
+
+struct rtx_def *
-+amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
-+ const_tree type, bool)
++amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool)
+{
+ DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p));
+
-+ struct amigaos_args *cum = *(struct amigaos_args **) get_cumulative_args (cum_v);
++ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
++
++ tree asmtree = type ? TYPE_ATTRIBUTES(cum->formal_type ? TREE_VALUE(cum->formal_type) : type) : NULL_TREE;
++ //tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
+
-+ tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
+ if (asmtree && 0 == strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
+ {
+ int i;
@@ -15242,17 +6338,17 @@ index 88205e25476e..ca8eea305345 100644
+ return _m68k_function_arg (cum, mode, type);
+}
+
-+void amiga_emit_regparm_clobbers(void)
++void
++amiga_emit_regparm_clobbers (void)
+{
-+ int x = 0;
+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (mycum.regs_already_used & (1 << i))
-+ emit_insn(gen_rtx_CLOBBER(Pmode, gen_raw_REG(Pmode, i)));
-+ }
++ if (mycum.regs_already_used & (1 << i))
++ {
++ rtx reg = gen_raw_REG (Pmode, i);
++ emit_insn (gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, gen_rtx_MEM(Pmode, reg))));
++ }
+}
+
-+
+/* 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). */
@@ -15265,167 +6361,238 @@ index 88205e25476e..ca8eea305345 100644
+ 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))
++ tree attrs1 = TYPE_ATTRIBUTES(type1);
++
++ tree asm1 = lookup_attribute("asmregs", attrs1);
++ tree stack1 = lookup_attribute("stkparm", attrs1);
++ tree reg1 = lookup_attribute("regparm", attrs1);
++
++ tree attrs2 = TYPE_ATTRIBUTES(type2);
++
++ tree asm2 = lookup_attribute("asmregs", attrs2);
++ tree stack2 = lookup_attribute("stkparm", attrs2);
++ tree reg2 = lookup_attribute("regparm", attrs2);
++
++ if (reg1)
+ {
-+ tree attr1 = TYPE_ATTRIBUTES(arg1);
-+ tree attr2 = TYPE_ATTRIBUTES(arg2);
-+ if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr1))))
-+ attr1 = NULL_TREE;
-+ if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr2))))
-+ attr2 = NULL_TREE;
-+ if (attr1 && attr2)
-+ {
-+ if (TREE_FIXED_CST_PTR(TREE_VALUE(attr1))->data.low
-+ != TREE_FIXED_CST_PTR(TREE_VALUE(attr2))->data.low)
-+ return 0;
-+ }
-+ else if (attr1 || attr2)
-+ return 0; /* asm attribute only on one side. */
++ if (stack2 || asm2)
++ return 0;
++
++ int no1 = TREE_INT_CST_LOW(TREE_VALUE(reg1));
++ int no2 = reg2 ? TREE_INT_CST_LOW(TREE_VALUE(reg2)) : amigaos_regparm;
++ return no1 == no2;
+ }
-+ if (arg1 || arg2)
-+ return 0; /* different count of parameters. */
-+ }
-+ return 1;
-+}
+
-+/* 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). */
-+#if 0
-+static int
-+m68k_comp_type_attributes (tree type1, tree type2)
-+{
++ if (reg2)
++ {
++ if (stack1 || asm1)
++ return 0;
+
-+ /* 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 no2 = TREE_INT_CST_LOW(TREE_VALUE(reg2));
++ return amigaos_regparm == no2;
++ }
++
++ if (stack1) {
++ if (stack2)
++ return 1;
++ return amigaos_regparm == 0;
++ }
++
++ if (stack2)
++ return amigaos_regparm == 0;
++
++ if (asm1)
+ {
-+ 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. */
++ if (!asm2)
++ return 0;
++
++ return 0 == strcmp(IDENTIFIER_POINTER(TREE_VALUE(asm1)), IDENTIFIER_POINTER(TREE_VALUE(asm2)));
+ }
++
++ if (asm2)
++ return 0;
++
++ }
++ else
++ {
++ tree attrs1 = TYPE_ATTRIBUTES(type1);
++
++ tree chip1 = lookup_attribute("chip", attrs1);
++ tree fast1 = lookup_attribute("fast", attrs1);
++ tree far1 = lookup_attribute("far", attrs1);
++
++ tree attrs2 = TYPE_ATTRIBUTES(type2);
++
++ tree chip2 = lookup_attribute("chip", attrs2);
++ tree fast2 = lookup_attribute("fast", attrs2);
++ tree far2 = lookup_attribute("far", attrs2);
++
++ if (chip1)
++ return chip2 && !fast2 && !far2;
++
++ if (fast1)
++ return !chip2 && fast2 && !far2;
++
++ if (far1)
++ return !chip2 && !fast2 && far2;
++
++ return !chip2 && !fast2 && !far2;
+ }
-+#ifdef TARGET_AMIGAOS
-+ return amigaos_comp_type_attributes(type1, type2);
-+#else
+ return 1;
-+#endif
+}
-+#endif
-+
+/* end-GG-local */
+
-+
-+/* Handle a "regparm", "stkparm" attribute;
++/* Handle a regparm, stkparm, saveds attribute;
+ arguments as in struct attribute_spec.handler. */
+tree
-+amigaos_handle_type_attribute (tree *node, tree name, tree args,
-+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
++amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ tree nnn = *node;
-+ do { // while (0);
-+ DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
-+ if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE
-+ || TREE_CODE (nnn) == 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))
++ do
++ { // while (0);
++ DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
++ if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE || TREE_CODE (nnn) == METHOD_TYPE)
+ {
-+ DPRINTF(("regparm found\n"));
-+
-+ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ if (args && TREE_CODE (args) == TREE_LIST)
++ /* 'regparm' accepts one optional argument - number of registers in
++ single class that should be used to pass arguments. */
++ if (is_attribute_p ("regparm", name))
+ {
-+ tree val = TREE_VALUE(args);
-+ DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
-+ if (TREE_CODE (val) == INTEGER_CST)
++ DPRINTF(("regparm found\n"));
++
++ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no < 0 || no > AMIGAOS_MAX_REGPARM)
++ error ("`regparm' and `stkparm' are mutually exclusive");
++ break;
++ }
++ if (args && TREE_CODE (args) == TREE_LIST)
++ {
++ tree val = TREE_VALUE(args);
++ DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
++ if (TREE_CODE (val) == INTEGER_CST)
++ {
++ int no = TREE_INT_CST_LOW(val);
++ if (no < 0 || no > AMIGAOS_MAX_REGPARM)
++ {
++ error ("`regparm' attribute: value %d not in [0 - %d]", no,
++ AMIGAOS_MAX_REGPARM);
++ break;
++ }
++ }
++ else
+ {
-+ error ("`regparm' attribute: value %d not in [0 - %d]",
-+ no,
-+ AMIGAOS_MAX_REGPARM);
++ error ("invalid argument(s) to `regparm' attribute");
+ break;
+ }
+ }
-+ else
++ }
++ else if (is_attribute_p ("stkparm", name))
++ {
++ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
+ {
-+ error ("invalid argument(s) to `regparm' attribute");
++ error ("`regparm' and `stkparm' are mutually exclusive");
+ break;
+ }
+ }
-+ }
-+ else if (is_attribute_p ("stkparm", name))
-+ {
-+ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
++ else if (is_attribute_p ("stackext", name))
+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
++ if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
++ {
++ error ("`stackext' and `interrupt' are mutually exclusive");
++ break;
++ }
++ }
++ else if (is_attribute_p ("saveds", name))
++ {
++ if (flag_pic < 3)
++ {
++ warning (OPT_Wattributes, "`%s' attribute is only usable with fbaserel", IDENTIFIER_POINTER(name));
++ }
++ else
++ if (flag_resident)
++ {
++ error ("`saveds' can't be used with resident!\n");
++ }
++ }
++ else
++ {
++ warning (OPT_Wattributes, "`%s' attribute only applies to data", IDENTIFIER_POINTER(name));
+ }
+ }
-+ else if (is_attribute_p ("stackext", name))
++ else
+ {
-+ if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
++ if (is_attribute_p ("chip", name) || is_attribute_p ("fast", name) || is_attribute_p ("far", name))
+ {
-+ error ("`stackext' and `interrupt' are mutually exclusive");
-+ break;
++ // OK
+ }
++ else
++ {
++ warning (OPT_Wattributes, "`%s' attribute only applies to functions", IDENTIFIER_POINTER(name));
++ }
++ }
++ return NULL_TREE ;
++ }
++ while (0);
++ // error case
++ *no_add_attrs = true;
++ return NULL_TREE ;
++}
++
++#define AMIGA_CHIP_SECTION_NAME ".datachip"
++#define AMIGA_FAST_SECTION_NAME ".datafast"
++#define AMIGA_FAR_SECTION_NAME ".datafar"
++
++void
++amiga_insert_attribute (tree decl, tree * attr)
++{
++ if (!*attr)
++ return;
++
++ tree name = TREE_PURPOSE(*attr);
++
++ if (is_attribute_p("chip", name) || is_attribute_p("far", name) || is_attribute_p("fast", name))
++ {
++ if (!TREE_TYPE(decl) == VAR_DECL)
++ {
++ error ("`%s' attribute can only be specified for variables", IDENTIFIER_POINTER(name));
++ return;
++ }
++
++ if (! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
++ {
++ error ("`%s' attribute cannot be specified for local variables", IDENTIFIER_POINTER(name));
++ return;
+ }
-+ else if (is_attribute_p ("saveds", name))
++
++ char const * section_name;
++ if (is_attribute_p("chip", name))
++ section_name = AMIGA_CHIP_SECTION_NAME;
++ else if (is_attribute_p("fast", name))
++ section_name = AMIGA_FAST_SECTION_NAME;
++ else if (is_attribute_p("far", name))
++ section_name = AMIGA_FAR_SECTION_NAME;
++
++
++ /* The decl may have already been given a section attribute from
++ a previous declaration. Ensure they match. */
++ if (DECL_SECTION_NAME (decl) == NULL)
++ set_decl_section_name(decl, section_name);
++ else if (strcmp (DECL_SECTION_NAME (decl), section_name) )
+ {
++ error_at (DECL_SOURCE_LOCATION(decl),
++ "`%s' attribute conflicts with previous declaration", IDENTIFIER_POINTER(name));
+ }
+ }
+ else
+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to functions",
-+ IDENTIFIER_POINTER(name));
++// warning (OPT_Wattributes, "`%s' attribute unknown", IDENTIFIER_POINTER(name));
+ }
-+ return NULL_TREE;
-+ } while (0);
-+ // error case
-+ *no_add_attrs = true;
-+ return NULL_TREE;
+}
+
-+
+extern bool
+m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+
+bool
-+amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
-+ int *total, bool speed)
++amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, bool speed)
+{
+// DPRINTF(("outer: %d, opno: %d", outer_code, opno));
+ bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
@@ -15435,3063 +6602,229 @@ index 88205e25476e..ca8eea305345 100644
+ return r;
+}
+
-+
+/* Output assembly to switch to section NAME with attribute FLAGS. */
-+
++#ifndef TARGET_AMIGAOS_VASM
+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
++amiga_named_section (const char *name, unsigned int flags, tree decl )
+{
-+ if (0 == strncmp(".text", name, 5))
++ // only one code section - TODO: with amiga hunk this is no longer mandatory.
++ if (0 == strncmp (".text", name, 5))
+ name = ".text";
-+ fprintf (asm_out_file, "\t%s\n", name);
++
++ if (0 == strncmp(".data", name, 5) && (!DECL_INITIAL (decl) || initializer_zerop (DECL_INITIAL (decl))))
++ fprintf (asm_out_file, "\t.bss%s\n", name + 5);
++ else
++ fprintf (asm_out_file, "\t%s\n", name);
+}
++#else
++extern void
++amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
++ {
++ if (0 == strncmp(".text", name, 5))
++ name = ".text";
++
++ if (0 == strncmp("section ", name, 8))
++ {
++// fprintf (asm_out_file, "\t.section\t%s\n", name);
++ fprintf (asm_out_file, "\t%s\n", name);
++ }
++ else
++ {
++ fprintf (asm_out_file, "\tsection %s\n", name);
++ }
++ }
++#endif
+
+/* Baserel support. */
+
+/**
+ * Does x reference the pic_reg and is const or plus?
+ */
-+int amiga_is_const_pic_ref(const_rtx x)
++static int
++_amiga_is_const_pic_ref (const_rtx x)
++{
++ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS)
++ {
++ if (GET_CODE(XEXP(x, 1)) == CONST_INT)
++ return _amiga_is_const_pic_ref(XEXP(x, 0));
++ return false;
++ }
++
++ if (GET_CODE(x) == CONST)
++ x = XEXP(x, 0);
++ if (GET_CODE(x) != PLUS)
++ return false;
++
++ const_rtx reg = XEXP(x, 0);
++ if (!REG_P(reg) && REGNO(reg) != PIC_REG)
++ return false;
++
++ const_rtx unspec = XEXP(x, 1);
++ while (GET_CODE(unspec) == PLUS || GET_CODE(unspec) == CONST)
++ unspec = XEXP(unspec, 0);
++
++ if (GET_CODE(unspec) != UNSPEC)
++ return false;
++
++ return true;
++}
++
++int
++amiga_is_const_pic_ref (const_rtx cnst)
+{
-+ const_rtx y = x;
+ if (flag_pic < 3)
+ return false;
-+ while (GET_CODE(y) == CONST || GET_CODE(y) == PLUS)
-+ y = XEXP(y, 0);
-+ return (x != y && REG_P(y) && REGNO(y) == PIC_REG);
++ int r = _amiga_is_const_pic_ref (cnst);
++// fprintf(stderr, r ? "valid pic: " : "invalid pic: ");
++// debug_rtx(cnst);
++ return r;
+}
+
+
+/* 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.
++ so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true.
+
-+ This function is used in base relative code generation. */
++ 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);
++ operand = XEXP(XEXP (operand, 0), 0);
+ if (GET_CODE (operand) == SYMBOL_REF)
-+ return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
++ return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P(operand);
+ return 1;
+}
+
-+reg_class_t
-+amiga_preferred_rename_class2 (reg_class_t rclass ATTRIBUTE_UNUSED, int regno)
++rtx
++amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED)
+{
-+ if (regno == 0)
-+ return D0_REGS;
-+ if (regno == 8)
-+ return A0_REGS;
-+ return regno_reg_class[regno];
++ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
+}
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 52eabeaafb23..3fabe00a678a 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -1004,6 +1004,8 @@ m68k_set_frame_related (rtx_insn *insn)
-
- /* Emit RTL for the "prologue" define_expand. */
-
-+extern void amiga_emit_regparm_clobbers(void);
-+
- void
- m68k_expand_prologue (void)
- {
-@@ -1012,6 +1014,10 @@ m68k_expand_prologue (void)
-
- m68k_compute_frame_layout ();
-
-+#ifdef TARGET_AMIGA
-+ amiga_emit_regparm_clobbers();
-+#endif
-+
- if (flag_stack_usage_info)
- current_function_static_stack_size
- = current_frame.size + current_frame.offset;
-
-From 9aabe6ab20a761ee0311e7f44fe8d32cc51fc5a2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 19 Apr 2017 14:40:38 +0200
-Subject: [PATCH 071/303] @B fix for 64bit builds
-
----
- gcc/config/m68k/amigaos.c | 16 +++++-----------
- 1 file changed, 5 insertions(+), 11 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index ca8eea305345..cf96844ad8cd 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -383,7 +383,7 @@ void
- amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- {
- struct amigaos_args * cum = decl == current_function_decl ? &mycum : &othercum;
-- *cump = (int)cum;
-+ *cump = decl == current_function_decl;
- cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
- DPRINTF(("0amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
-
-@@ -459,7 +459,7 @@ void
- amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree,
- bool)
- {
-- struct amigaos_args *cum = *(struct amigaos_args **) get_cumulative_args (cum_v);
-+ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
- /* Update the data in CUM to advance over an argument. */
-
- DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cump));
-@@ -487,9 +487,6 @@ amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree,
- CUM is a variable of type CUMULATIVE_ARGS which gives info about
- the preceding args and about the function being called. */
-
--static struct rtx_def *
--_m68k_function_arg (CUMULATIVE_ARGS *, machine_mode, const_tree);
--
- static struct rtx_def *
- _m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree type)
- {
-@@ -567,7 +564,7 @@ amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
- {
- DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p));
-
-- struct amigaos_args *cum = *(struct amigaos_args **) get_cumulative_args (cum_v);
-+ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
-
- tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
- if (asmtree && 0 == strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-@@ -592,12 +589,9 @@ amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
-
- void amiga_emit_regparm_clobbers(void)
- {
-- int x = 0;
- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-- {
-- if (mycum.regs_already_used & (1 << i))
-- emit_insn(gen_rtx_CLOBBER(Pmode, gen_raw_REG(Pmode, i)));
-- }
-+ if (mycum.regs_already_used & (1 << i))
-+ emit_insn(gen_rtx_CLOBBER(Pmode, gen_raw_REG(Pmode, i)));
- }
-
-
-
-From aad2b7a890503955a2a1aae5ab09f89ed1466769 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 19 Apr 2017 18:37:57 +0200
-Subject: [PATCH 072/303] @R mregparm is using old register usage conventions
-
----
- gcc/config/m68k/amigaos.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index cf96844ad8cd..09934f94c06d 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -537,7 +537,7 @@ _m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree typ
- }
- }
-
-- if (reg == AMIGAOS_MAX_REGPARM && altregbegin != -1)
-+ if (reg == cum->num_of_regs && altregbegin != -1)
- {
- DPRINTF(("look for alt reg\n"));
- regbegin = altregbegin;
-
-From 554f57921f19cad9583eb4f319e12710ab786ceb Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 19 Apr 2017 18:40:05 +0200
-Subject: [PATCH 073/303] @B ensure that clobbers for mregparm are not marked
- as REG_DEAD
-
----
- gcc/bbb-opts.c | 43 ++++++++++++++++++++++++++++---------------
- gcc/regrename.c | 28 ++++++++++++++++++++++++++--
- 2 files changed, 54 insertions(+), 17 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 1b1863e9ae8f..2c19242512a2 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -325,20 +325,24 @@ dump_insns (char const * name, bool all)
- }
- for (unsigned i = 0; i < insns.size (); ++i)
- {
-- insn_info & ii = infos[i];
--
- fprintf (stderr, "%d: ", i);
-
-- for (int j = 0; j < 8; ++j)
-- if (ii.is_use (j))
-- fprintf (stderr, ii.is_def (j) ? "*d%d " : "d%d ", j);
-+ if (i < infos.size ())
-+ {
-+ insn_info & ii = infos[i];
-+
-+ for (int j = 0; j < 8; ++j)
-+ if (ii.is_use (j))
-+ fprintf (stderr, ii.is_def (j) ? "*d%d " : "d%d ", j);
-
-- for (int j = 8; j < 16; ++j)
-- if (ii.is_use (j))
-- fprintf (stderr, ii.is_def (j) ? "*a%d " : "a%d ", j - 8);
-+ for (int j = 8; j < 16; ++j)
-+ if (ii.is_use (j))
-+ fprintf (stderr, ii.is_def (j) ? "*a%d " : "a%d ", j - 8);
-
-- if (ii.is_use (FIRST_PSEUDO_REGISTER))
-- fprintf (stderr, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc ");
-+ if (ii.is_use (FIRST_PSEUDO_REGISTER))
-+ fprintf (stderr, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc ");
+
-+ }
-
- fprintf (stderr, "\t");
- debug_rtx (insns[i]);
-@@ -502,6 +506,14 @@ update_insn_infos (void)
- continue;
- }
-
-+ if (GET_CODE (pattern) == CLOBBER ) {
-+ /* mark regs as use and def */
-+ insn_info ud;
-+ ud.scan(pattern);
-+ ud._def |= ud._use;
-+ infos[pos] |= ud;
-+ continue;
-+ }
- if (GET_CODE (pattern) != PARALLEL && GET_CODE (pattern) != CLOBBER && be_verbose)
- {
- fprintf (stderr, "##### ");
-@@ -882,7 +894,7 @@ opt_strcpy ()
- src = XEXP(src, 1);
-
- // if (CONST_INT_P(src) && INTVAL(src) == 0 && find_reg_note (insn, REG_DEAD, dst))
-- if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 && is_reg_dead(REGNO(dst), index))
-+ if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 && is_reg_dead (REGNO(dst), index))
- {
- /* now check via NOTICE_UPDATE_CC*/
- NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
-@@ -1300,7 +1312,7 @@ merge_add (void)
-
- log ("merge_add applied\n");
-
-- rtx_insn * newins1 = make_insn_raw(gen_rtx_SET(dst1, l1));
-+ rtx_insn * newins1 = make_insn_raw (gen_rtx_SET(dst1, l1));
- add_insn_after (newins1, ins1, 0);
- SET_INSN_DELETED(ins1);
-
-@@ -1836,9 +1848,9 @@ namespace
- class opt_pass * rr = ::global_pass_regrename->clone ();
- rr->execute (0);
-
-- // update_insns ();
-- // update_insn_infos ();
-- // bb_reg_rename ();
-+ // update_insns ();
-+ // update_insn_infos ();
-+ // bb_reg_rename ();
-
- update_insns ();
- }
-@@ -1851,6 +1863,7 @@ namespace
- {
- shrink_stack_frame ();
- update_insns ();
-+ update_insn_infos ();
- }
-
- if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index 696e5557780e..eceb7286e31e 100755
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -892,7 +892,7 @@ regrename_analyze (bitmap bb_mask)
- if (!range_overlaps_hard_reg_set_p (live, chain->regno,
- chain->nregs))
- continue;
--
-+
- n_succs_used++;
-
- dest_ri = (struct bb_rename_info *)e->dest->aux;
-@@ -916,7 +916,7 @@ regrename_analyze (bitmap bb_mask)
- printed = true;
- fprintf (dump_file,
- " merging chains %d (->%d) and %d (->%d) [%s]\n",
-- k, incoming_chain->id, j, chain->id,
-+ k, incoming_chain->id, j, chain->id,
- reg_names[incoming_chain->regno]);
- }
-
-@@ -1892,6 +1892,28 @@ regrename_finish (void)
- obstack_free (&rename_obstack, NULL);
- }
-
-+void
-+mark_early_clobbers_alive (void)
++rtx
++amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
+{
-+ rtx_insn * insn;
-+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-+ {
-+ rtx pattern;
-+ if (NOTE_P(insn) && NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-+ break;
-+
-+ pattern = PATTERN (insn);
-+ if (pattern && GET_CODE(pattern) == CLOBBER)
-+ {
-+ rtx *loc;
-+
-+ loc = &REG_NOTES(insn);
-+ while (*loc)
-+ *loc = XEXP(*loc, 1);
-+ }
-+ }
-+}
-+
- /* Perform register renaming on the current function. */
-
- static unsigned int
-@@ -1902,6 +1924,8 @@ regrename_optimize (void)
- df_analyze ();
- df_set_flags (DF_DEFER_INSN_RESCAN);
-
-+ mark_early_clobbers_alive ();
++ if (!decl || !DECL_STATIC_CHAIN(decl))
++ return 0;
+
- regrename_init (false);
-
- regrename_analyze (NULL);
-
-From 23951fbf9ef78f3106624afd857e738ee56d3663 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 20 Apr 2017 09:34:00 +0200
-Subject: [PATCH 074/303] @B modified clobber for regrename with regparm
-
----
- gcc/config/m68k/amigaos.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 09934f94c06d..a598406ca132 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -591,7 +591,10 @@ void amiga_emit_regparm_clobbers(void)
- {
- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- if (mycum.regs_already_used & (1 << i))
-- emit_insn(gen_rtx_CLOBBER(Pmode, gen_raw_REG(Pmode, i)));
++ unsigned used = 0;
++ tree fntype = TREE_TYPE(decl);
++ if (fntype)
++ for (tree formal_type = TYPE_ARG_TYPES(fntype); formal_type; formal_type = TREE_CHAIN(formal_type))
+ {
-+ rtx reg = gen_raw_REG(Pmode, i);
-+ emit_insn(gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, reg)));
-+ }
- }
-
-
-
-From 6186c919f785d5f0ed760ac3e164510098e106aa Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 20 Apr 2017 18:29:48 +0200
-Subject: [PATCH 075/303] @R half way through to own rename
-
----
- gcc/bbb-opts.c | 240 +++++++++++++++++++++++++++++++++++++++-------
- gcc/config/m68k/amigaos.c | 3 +-
- gcc/regrename.c | 26 +----
- 3 files changed, 208 insertions(+), 61 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 2c19242512a2..7a3a716193c4 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -49,6 +49,7 @@
- #include "cselib.h"
- #include "langhooks.h"
- #include <vector>
-+#include <set>
- #include <map>
-
- static bool be_verbose;
-@@ -94,11 +95,12 @@ log (char const * fmt, ...)
- */
- struct insn_info
- {
-- unsigned _use;
-- unsigned _def;
-+ unsigned _use; // bit set if registers are used
-+ unsigned _def; // bit set if registers are defined
-+ unsigned _hard; // bit set if registers can't be renamed
-
- insn_info () :
-- _use (0), _def (0)
-+ _use (0), _def (0), _hard (0)
- {
- }
-
-@@ -107,6 +109,7 @@ struct insn_info
- {
- _use = 0;
- _def = 0;
-+ _hard = 0;
- }
-
- inline void
-@@ -121,11 +124,18 @@ struct insn_info
- _def |= 1 << regno;
- }
-
-+ inline void
-+ hard (int regno)
-+ {
-+ _hard |= 1 << regno;
-+ }
-+
- inline void
- unset (int regno)
- {
- _use &= ~(1 << regno);
- _def &= ~(1 << regno);
-+ _hard &= ~(1 << regno);
- }
-
- inline bool
-@@ -140,12 +150,19 @@ struct insn_info
- return (_def & (1 << regno)) != 0;
- }
-
-+ inline bool
-+ is_hard (int regno)
-+ {
-+ return (_hard & (1 << regno)) != 0;
-+ }
++ tree asmtree = TYPE_ATTRIBUTES(TREE_VALUE(formal_type));
++ if (!asmtree || strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
++ continue;
+
- inline insn_info
- operator | (insn_info const & o) const
- {
- insn_info t;
- t._use = _use | o._use;
- t._def = _def | o._def;
-+ t._hard = _hard | o._hard;
- return t;
- }
-
-@@ -154,6 +171,7 @@ struct insn_info
- {
- _use |= o._use;
- _def |= o._def;
-+ _hard |= o._hard;
- return *this;
- }
-
-@@ -162,6 +180,7 @@ struct insn_info
- {
- _use &= o._use & o._def;
- _def &= o._def;
-+ _hard &= o._hard & o._def;
- return *this;
- }
-
-@@ -177,6 +196,7 @@ struct insn_info
- insn_info t;
- t._use = ~_use;
- t._def = ~_def;
-+ t._hard = ~_hard;
- return t;
- }
-
-@@ -194,9 +214,12 @@ struct insn_info
- scan (rtx);
-
- unsigned
-- get_def_mask () const
-+ get_free_mask () const
- {
-- if (!_def || _def > 0x7fff)
-+ if (_def & _hard)
-+ return 0;
++ unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
++ used |= 1 << regno;
++ }
+
-+ if (!_def || _def > 0x1000)
- return 0;
-
- unsigned mask = _def - 1;
-@@ -204,11 +227,10 @@ struct insn_info
- if ((mask & ~_def) != mask)
- return 0;
-
-- if (_def > 0x1000)
-- return 0;
- if (_def > 0xff)
- mask &= 0xff00;
-- return mask;
++ if (!(used & (1 << 9)))
++ return gen_rtx_REG (Pmode, 9);
++ if (!(used & (1 << 10)))
++ return gen_rtx_REG (Pmode, 10);
++ if (!(used & (1 << 11)))
++ return gen_rtx_REG (Pmode, 11);
++ if (!(used & (1 << 14)))
++ return gen_rtx_REG (Pmode, 14);
+
-+ return mask & ~_use;
- }
- };
-
-@@ -271,6 +293,7 @@ do_reg_rename (rtx x, unsigned oldregno, unsigned newregno)
- * Collect some data.
- */
- static std::vector<rtx_insn *> insns;
-+static std::vector<bool> proepilogue;
- static std::vector<rtx_insn *> temp;
- static std::vector<rtx_insn *> jumps;
- static std::map<rtx_insn *, unsigned> insn2index;
-@@ -283,6 +306,7 @@ static void
- clear (void)
- {
- insns.clear ();
-+ proepilogue.clear ();
- jumps.clear ();
- insn2index.clear ();
- infos.clear ();
-@@ -333,11 +357,23 @@ dump_insns (char const * name, bool all)
-
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j))
-- fprintf (stderr, ii.is_def (j) ? "*d%d " : "d%d ", j);
-+ {
-+ if (ii.is_hard (j))
-+ fprintf (stderr, "!");
-+ if (ii.is_def (j))
-+ fprintf (stderr, "*");
-+ fprintf (stderr, "d%d ", j);
-+ }
-
- for (int j = 8; j < 16; ++j)
- if (ii.is_use (j))
-- fprintf (stderr, ii.is_def (j) ? "*a%d " : "a%d ", j - 8);
-+ {
-+ if (ii.is_hard (j))
-+ fprintf (stderr, "!");
-+ if (ii.is_def (j))
-+ fprintf (stderr, "*");
-+ fprintf (stderr, "a%d ", j - 8);
-+ }
-
- if (ii.is_use (FIRST_PSEUDO_REGISTER))
- fprintf (stderr, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc ");
-@@ -367,6 +403,7 @@ update_insns ()
-
- df_insn_rescan_all ();
-
-+ bool inproepilogue = true;
- /* create a vector with relevant insn. */
- for (insn = get_insns (); insn; insn = next)
- {
-@@ -379,6 +416,18 @@ update_insns ()
-
- insn2index.insert (std::make_pair (insn, insns.size ()));
- insns.push_back (insn);
-+ proepilogue.push_back (inproepilogue);
++ return 0;
++}
+
-+ if (JUMP_P(insn))
-+ inproepilogue = false;
-+ }
++/**
++ * Necessary to block some funny invalid combinations if baserel is used:
++ *
++(const:SI (minus:SI (neg:SI (reg:SI 12 a4))
++ (const:SI (plus:SI (unspec:SI [
++ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
++ (const_int 0 [0])
++ ] 6)
+
-+ if (NOTE_P(insn))
-+ {
-+ if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-+ inproepilogue = false;
-+ else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
-+ inproepilogue = true;
- }
- }
- }
-@@ -447,6 +496,8 @@ update_insn_infos (void)
- for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
- use.use (r);
- }
-+ /* also mark all registers as not renamable */
-+ use._hard = use._use;
-
- rtx set = single_set (insn);
- if (set)
-@@ -457,15 +508,11 @@ update_insn_infos (void)
- else
- use.scan (pattern);
-
-- /* fix missing defs - a call sets d0 and maybe also d1,a0,a1. */
-- if (ii.is_use (0))
-- def.def (0);
-- if (ii.is_use (1))
-- def.def (1);
-- if (ii.is_use (8))
-- def.def (8);
-- if (ii.is_use (9))
-- def.def (9);
-+ /* mark scratch registers. */
-+ def.def (0);
-+ def.def (1);
-+ def.def (8);
-+ def.def (9);
-
- infos[pos] = def | use | ii;
-
-@@ -501,26 +548,37 @@ update_insn_infos (void)
- {
- rtx x = XEXP(pattern, 0);
- if (REG_P(x))
-- ii.use (REGNO(x));
-+ {
-+ ii.use (REGNO(x));
-+ ii.hard (REGNO(x));
-+ }
- infos[pos] = ii;
- continue;
- }
-
-- if (GET_CODE (pattern) == CLOBBER ) {
-+ if (GET_CODE (pattern) == CLOBBER)
-+ {
- /* mark regs as use and def */
- insn_info ud;
-- ud.scan(pattern);
-+ ud.scan (pattern);
- ud._def |= ud._use;
-+ ud._hard = ud._use; /* don't rename. */
- infos[pos] |= ud;
- continue;
-- }
-- if (GET_CODE (pattern) != PARALLEL && GET_CODE (pattern) != CLOBBER && be_verbose)
-+ }
-+ if (GET_CODE (pattern) != PARALLEL && be_verbose)
- {
- fprintf (stderr, "##### ");
- debug_rtx (insn);
- }
-- ii.scan (pattern);
-- infos[pos] = ii;
-+
-+ insn_info jj;
-+ jj.scan (pattern);
-+
-+ if (proepilogue[pos])
-+ jj._hard = jj._use | jj._def;
-+
-+ infos[pos] = ii | jj;
- continue;
- }
-
-@@ -549,6 +607,9 @@ update_insn_infos (void)
- def.def (FIRST_PSEUDO_REGISTER);
- }
-
-+ if (proepilogue[pos])
-+ ii._hard |= use._use | def._def;
++(plus:SI (reg:SI 10 a2)
++ (const:SI (minus:SI (neg:SI (reg:SI 12 a4))
++ (const:SI (plus:SI (unspec:SI [
++ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
++ (const_int 0 [0])
++ ] 6)
++ (const_int 1234 [0xe00]))))))) xyz.c:41 465 {*lea}
+
- infos[pos] = def | use | ii;
-
- ii &= ~def;
-@@ -558,6 +619,114 @@ update_insn_infos (void)
- }
- }
-
-+static int
-+bit2regno (unsigned bit)
++ */
++bool
++amigaos_legitimate_src (rtx src)
+{
-+ if (!bit)
-+ return -1;
++ if (flag_pic < 3)
++ return true;
+
-+ unsigned regno = 0;
-+ while (!(bit & 1))
++ if (MEM_P(src))
+ {
-+ ++regno;
-+ bit >>= 1;
++ rtx x = XEXP(src, 0);
++ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS) {
++ if (amiga_is_const_pic_ref(XEXP(x, 0))
++ || amiga_is_const_pic_ref(XEXP(x, 1)))
++ return false;
++ }
++ return true;
+ }
-+ return regno;
-+}
+
-+/*
-+ * Always prefer lower register numbers within the class.
-+ */
-+static unsigned
-+bb_reg_rename (void)
-+{
-+// dump_insns ("rename", 1);
-+ for (unsigned index = 0; index < insns.size (); ++index)
++ if (GET_CODE(src) == PLUS || GET_CODE(src) == MINUS)
+ {
-+ insn_info & ii = infos[index];
-+ const unsigned def = ii._def & ~ii._hard;
-+ unsigned mask = ii.get_free_mask ();
-+
-+ if (!mask || !def)
-+ continue;
-+
-+ std::set<unsigned> found;
-+ std::vector<unsigned> todo;
-+ if (index + 1 < insns.size ())
-+ todo.push_back (index + 1);
-+
-+ found.insert (index);
-+ /* a register was defined, follow all branches. */
-+ while (todo.size ())
-+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
-+
-+ if (found.find (pos) != found.end ())
-+ continue;
-+
-+ if (LABEL_P(insns[pos]))
-+ {
-+ if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
-+ continue;
-+ }
-+
-+ insn_info & jj = infos[pos];
-+
-+ /* not used. */
-+ if (!(jj._use & def))
-+ continue;
-+
-+ /* update free regs. */
-+ mask &= ~jj._use;
-+ mask &= ~jj._def;
-+ if (!mask)
-+ break;
-+
-+
-+ found.insert (pos);
-+
-+ /* follow jump and/or next insn. */
-+ rtx_insn * insn = insns[pos];
-+ if (JUMP_P(insn))
-+ {
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-+ if (j != insn2index.end ())
-+ todo.push_back (j->second);
-+
-+ rtx jmppattern = PATTERN (insn);
-+
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-+ if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
-+ }
-+ else if (pos + 1 < insns.size ())
-+ todo.push_back (pos + 1);
-+ }
-+
-+ if (mask)
-+ {
-+ int oldregno = bit2regno (def);
-+ int newregno = bit2regno (mask);
-+ log ("bb_reg_rename %s -> %s (%d insns)\n", reg_names[oldregno], reg_names[newregno], found.size ());
-+
-+ for (std::set<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
-+ {
-+// if (be_verbose)
-+// debug_rtx (insns[*i]);
-+ do_reg_rename (PATTERN (insns[*i]), oldregno, newregno);
-+ }
-+
-+ cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
-+ cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
- /*
- * #1 propagate a->b->a moves out of a loop.
- *
-@@ -1841,18 +2010,19 @@ namespace
- done = 0, update_insns (), update_insn_infos ();
-
- if (do_elim_dead_assign && elim_dead_assign ())
-- done = 0, update_insns ();
-+ done = 0, update_insns (), update_insn_infos ();
-
- if (do_bb_reg_rename && ::global_pass_regrename)
- {
-- class opt_pass * rr = ::global_pass_regrename->clone ();
-- rr->execute (0);
--
-- // update_insns ();
-- // update_insn_infos ();
-- // bb_reg_rename ();
--
-- update_insns ();
-+// class opt_pass * rr = ::global_pass_regrename->clone ();
-+// rr->execute (0);
++ rtx x = XEXP(src, 0);
++ rtx y = XEXP(src, 1);
+
-+ while (bb_reg_rename ())
-+ {
-+ update_insns ();
-+ update_insn_infos ();
-+ done = 0;
-+ }
- }
-
- if (done)
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index a598406ca132..dd5707612119 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -589,11 +589,12 @@ amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
-
- void amiga_emit_regparm_clobbers(void)
- {
-+ rtx sp = gen_raw_REG(Pmode, 15);
- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- if (mycum.regs_already_used & (1 << i))
- {
- rtx reg = gen_raw_REG(Pmode, i);
-- emit_insn(gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, reg)));
-+ emit_insn(gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, gen_rtx_MEM(Pmode, reg))));
- }
- }
-
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index eceb7286e31e..fad839f8f926 100755
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -1892,28 +1892,6 @@ regrename_finish (void)
- obstack_free (&rename_obstack, NULL);
- }
-
--void
--mark_early_clobbers_alive (void)
--{
-- rtx_insn * insn;
-- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-- {
-- rtx pattern;
-- if (NOTE_P(insn) && NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-- break;
--
-- pattern = PATTERN (insn);
-- if (pattern && GET_CODE(pattern) == CLOBBER)
-- {
-- rtx *loc;
--
-- loc = &REG_NOTES(insn);
-- while (*loc)
-- *loc = XEXP(*loc, 1);
-- }
-- }
--}
--
- /* Perform register renaming on the current function. */
-
- static unsigned int
-@@ -1924,8 +1902,6 @@ regrename_optimize (void)
- df_analyze ();
- df_set_flags (DF_DEFER_INSN_RESCAN);
-
-- mark_early_clobbers_alive ();
--
- regrename_init (false);
-
- regrename_analyze (NULL);
-@@ -1965,7 +1941,7 @@ class pass_regrename : public rtl_opt_pass
- /* opt_pass methods: */
- virtual bool gate (function *)
- {
-- return (optimize > 0 && (flag_rename_registers));
-+ return (optimize > 0 && (flag_rename_registers) && !TARGET_AMIGA);
- }
-
- virtual unsigned int execute (function *) { return regrename_optimize (); }
-
-From bab57d7745f2399e3bf6c23f9803ae188bf576ea Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 22 Apr 2017 16:23:35 +0200
-Subject: [PATCH 076/303] @R own rename registers seems to work.
-
----
- gcc/bbb-opts.c | 350 ++++++++++++++++++++++++++++++++++++--------------------
- gcc/cfgbuild.c | 1 +
- gcc/regrename.c | 3 -
- 3 files changed, 225 insertions(+), 129 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 7a3a716193c4..1f70ffecc2d4 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -175,13 +175,20 @@ struct insn_info
- return *this;
- }
-
-- inline insn_info &
-- operator &= (insn_info const & o)
-+ /*
-+ * update for previous insn.
-+ * - remove regs which are defined here
-+ * - add regs which are used here
-+ * - reset _def
-+ * - restrain _hard to used
-+ */
-+ inline void
-+ updateWith (insn_info const & o)
- {
-- _use &= o._use & o._def;
-- _def &= o._def;
-- _hard &= o._hard & o._def;
-- return *this;
-+ _use &= ~o._def;
-+ _use |= o._use;
-+ _def = 0;
-+ _hard &= ~_use;
- }
-
- inline bool
-@@ -252,6 +259,24 @@ insn_info::scan (rtx x)
- }
-
- RTX_CODE code = GET_CODE(x);
++ /** handled in print_operand_address(...) */
++ if (amiga_is_const_pic_ref(x))
++ return GET_CODE(y) == CONST_INT;
+
-+ /* handle SET and record use and def. */
-+ if (code == SET)
-+ {
-+ unsigned u = _use;
-+ scan (SET_DEST(x));
-+ if (REG_P(SET_DEST(x)))
-+ {
-+ _def = _use;
-+ _use = u;
-+ }
-+ scan (SET_SRC(x));
-+ int code = GET_CODE(SET_SRC(x));
-+ if (code == ASM_OPERANDS)
-+ _hard |= _def | _use;
-+ return;
++ return amigaos_legitimate_src(x) && amigaos_legitimate_src(y) && !amiga_is_const_pic_ref(y);
+ }
+
- const char *fmt = GET_RTX_FORMAT(code);
- for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
-@@ -263,14 +288,63 @@ insn_info::scan (rtx x)
- }
- }
-
-+static rtx
-+copy_reg(rtx reg, int newregno)
-+{
-+ if (newregno < 0)
-+ newregno = REGNO(reg);
-+ rtx x = gen_raw_REG(GET_MODE(reg), newregno);
-+ x->jump = reg->jump;
-+ x->call = reg->call;
-+ x->unchanging = reg->unchanging;
-+ x->volatil = reg->volatil;
-+ x->in_struct = reg->in_struct;
-+ x->used = reg->used;
-+ x->frame_related = reg->frame_related;
-+ x->return_val = reg->return_val;
-+
-+ x->u.reg.attrs = reg->u.reg.attrs;
-+ return x;
-+}
-+
-+static void
-+validate_rename (std::vector<std::pair<rtx *, rtx>> & loc, rtx x, unsigned oldregno, unsigned newregno)
-+{
-+ RTX_CODE code = GET_CODE(x);
-+
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
++ if (GET_CODE(src) == CONST)
+ {
-+ if (fmt[i] == 'e')
++ rtx op = XEXP(src, 0);
++ if (GET_CODE(op) == MINUS || GET_CODE(op) == PLUS)
+ {
-+ rtx y = XEXP(x, i);
-+ if (REG_P(y))
-+ {
-+ if (REGNO(y) == oldregno)
-+ {
-+ rtx z = copy_reg(y, newregno);
-+ loc.push_back (std::make_pair (&XEXP(x, i), y));
-+ XEXP(x, i) = z;
-+ }
-+ }
-+ else
-+ validate_rename (loc, y, oldregno, newregno);
-+ }
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ validate_rename (loc, XVECEXP(x, i, j), oldregno, newregno);
-+ }
-+}
-+
- /* perform reg renaming. */
- static void
--do_reg_rename (rtx x, unsigned oldregno, unsigned newregno)
-+do_reg_rename (rtx * loc, unsigned oldregno, unsigned newregno)
- {
-+ rtx x = *loc;
- if (REG_P(x))
- {
- if (REGNO(x) == oldregno)
-- df_ref_change_reg_with_loc (x, newregno);
-+ *loc = copy_reg(x, newregno);
- return;
- }
-
-@@ -282,10 +356,10 @@ do_reg_rename (rtx x, unsigned oldregno, unsigned newregno)
- for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
-- do_reg_rename (XEXP(x, i), oldregno, newregno);
-+ do_reg_rename (&XEXP(x, i), oldregno, newregno);
- else if (fmt[i] == 'E')
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-- do_reg_rename (XVECEXP(x, i, j), oldregno, newregno);
-+ do_reg_rename (&XVECEXP(x, i, j), oldregno, newregno);
- }
- }
-
-@@ -356,7 +430,7 @@ dump_insns (char const * name, bool all)
- insn_info & ii = infos[i];
-
- for (int j = 0; j < 8; ++j)
-- if (ii.is_use (j))
-+ if (ii.is_use (j) || ii.is_def (j))
- {
- if (ii.is_hard (j))
- fprintf (stderr, "!");
-@@ -366,7 +440,7 @@ dump_insns (char const * name, bool all)
- }
-
- for (int j = 8; j < 16; ++j)
-- if (ii.is_use (j))
-+ if (ii.is_use (j) || ii.is_def (j))
- {
- if (ii.is_hard (j))
- fprintf (stderr, "!");
-@@ -436,15 +510,15 @@ static void
- update_insn_infos (void)
- {
- /* prepare insn_info */
-- insn_info ii;
-+ insn_info ii0;
- for (unsigned i = 0; i < insns.size (); ++i)
- {
-- infos.push_back (ii);
-+ infos.push_back (ii0);
- }
-
- /* own analyze reg life */
- std::vector<std::pair<unsigned, insn_info>> todo;
-- todo.push_back (std::make_pair (insns.size () - 1, ii));
-+ todo.push_back (std::make_pair (insns.size () - 1, ii0));
-
- int pass = 0;
- while (!todo.empty ())
-@@ -484,7 +558,6 @@ update_insn_infos (void)
-
- if (CALL_P(insn))
- {
-- insn_info def;
- insn_info use;
-
- /* add mregparm registers. */
-@@ -499,25 +572,16 @@ update_insn_infos (void)
- /* also mark all registers as not renamable */
- use._hard = use._use;
-
-- rtx set = single_set (insn);
-- if (set)
-- {
-- use.scan (SET_SRC(set));
-- def.scan (SET_DEST(set));
-- }
-- else
-- use.scan (pattern);
-+ use.scan (pattern);
-
- /* mark scratch registers. */
-- def.def (0);
-- def.def (1);
-- def.def (8);
-- def.def (9);
--
-- infos[pos] = def | use | ii;
-+ use.def (0);
-+ use.def (1);
-+ use.def (8);
-+ use.def (9);
-
-- ii &= ~def;
-- ii |= use;
-+ infos[pos] = use | ii;
-+ ii.updateWith (use);
-
- continue;
- }
-@@ -525,95 +589,60 @@ update_insn_infos (void)
- if (JUMP_P(insn))
- {
- if (ANY_RETURN_P(pattern))
-- {
-- ii.reset ();
--// ii.use (0);
-- }
-- else
-- {
-- ii |= infos[pos];
-+ ii.reset ();
-
-- // check for reg use
-- ii.scan (PATTERN (insn));
-+ insn_info use;
-+ use.scan (pattern);
-+ infos[pos] = use | ii;
-+ ii.updateWith (use);
-
-- }
-- infos[pos] = ii;
- continue;
- }
-
-- rtx set = single_set (insn);
-- if (set == 0)
-+ if (GET_CODE (pattern) == USE)
- {
-- if (GET_CODE (pattern) == USE)
-- {
-- rtx x = XEXP(pattern, 0);
-- if (REG_P(x))
-- {
-- ii.use (REGNO(x));
-- ii.hard (REGNO(x));
-- }
-- infos[pos] = ii;
-- continue;
-- }
--
-- if (GET_CODE (pattern) == CLOBBER)
-- {
-- /* mark regs as use and def */
-- insn_info ud;
-- ud.scan (pattern);
-- ud._def |= ud._use;
-- ud._hard = ud._use; /* don't rename. */
-- infos[pos] |= ud;
-- continue;
-- }
-- if (GET_CODE (pattern) != PARALLEL && be_verbose)
-+ rtx x = XEXP(pattern, 0);
-+ if (REG_P(x))
- {
-- fprintf (stderr, "##### ");
-- debug_rtx (insn);
-+ ii.use (REGNO(x));
-+ ii.hard (REGNO(x));
- }
-+ infos[pos] = ii;
-+ continue;
-+ }
-
-- insn_info jj;
-- jj.scan (pattern);
--
-- if (proepilogue[pos])
-- jj._hard = jj._use | jj._def;
--
-- infos[pos] = ii | jj;
-+ if (GET_CODE (pattern) == CLOBBER)
-+ {
-+ /* mark regs as use and def */
-+ insn_info use;
-+ use.scan (pattern);
-+ use._hard = use._use = use._def = use._use | use._def;
-+ infos[pos] = use | ii;
-+ ii.updateWith (use);
- continue;
- }
-
-- rtx src = SET_SRC(set);
-- rtx dst = SET_DEST(set);
-- // scan insn for regs
-- // a def stop propagation
-- // a use starts propagation
-- // also add use to current ii
- insn_info use;
-- insn_info def;
--
-- use.scan (src);
-- if (REG_P(dst))
-- def.def (REGNO(dst));
-- else if (dst == cc0_rtx)
-- def.def (FIRST_PSEUDO_REGISTER);
-- else
-- use.scan (dst);
-+ use.scan (pattern);
-+ if (single_set (insn) == 0)
-+ use._hard = use._use | use._def;
-
-- if (dst != cc0_rtx)
-+ /* if not cc0 defined check for mod. */
-+ if (!use.is_def (FIRST_PSEUDO_REGISTER))
- {
- CC_STATUS_INIT;
- NOTICE_UPDATE_CC(PATTERN (insn), insn);
- if (cc_status.value1 || cc_status.value2)
-- def.def (FIRST_PSEUDO_REGISTER);
-+ use.def (FIRST_PSEUDO_REGISTER);
- }
-
-+ /* mark not renameable in prologue/epilogue. */
- if (proepilogue[pos])
-- ii._hard |= use._use | def._def;
--
-- infos[pos] = def | use | ii;
-+ use._hard = use._use | use._def;
-
-- ii &= ~def;
-- ii |= use;
-+ ii._use &= ~use._def;
-+ infos[pos] = use | ii;
-+ ii.updateWith (use);
- }
- ++pass;
- }
-@@ -644,10 +673,15 @@ bb_reg_rename (void)
- for (unsigned index = 0; index < insns.size (); ++index)
- {
- insn_info & ii = infos[index];
-- const unsigned def = ii._def & ~ii._hard;
-- unsigned mask = ii.get_free_mask ();
-
-- if (!mask || !def)
-+ /* do not rename if register is hard or used in same statement. */
-+ const unsigned toRename = ii._def & ~ii._hard & ~ii._use;
-+ if (!toRename)
-+ continue;
-+
-+ /* get the mask for free registers. */
-+ unsigned mask = ii.get_free_mask ();
-+ if (!mask)
- continue;
-
- std::set<unsigned> found;
-@@ -675,16 +709,22 @@ bb_reg_rename (void)
- insn_info & jj = infos[pos];
-
- /* not used. */
-- if (!(jj._use & def))
-+ if (!(jj._use & toRename))
- continue;
-
-+ /* marked as hard reg -> invalid rename */
-+ if (jj._hard & toRename)
++ rtx x = XEXP(op, 0);
++ if (GET_CODE(x) == NOT || GET_CODE(x) == NEG || GET_CODE(x) == SIGN_EXTEND)
+ {
-+ mask = 0;
-+ break;
-+ }
-+
- /* update free regs. */
- mask &= ~jj._use;
- mask &= ~jj._def;
- if (!mask)
- break;
-
--
- found.insert (pos);
-
- /* follow jump and/or next insn. */
-@@ -696,6 +736,11 @@ bb_reg_rename (void)
- todo.push_back (j->second);
-
- rtx jmppattern = PATTERN (insn);
-+ if (GET_CODE(jmppattern) == PARALLEL)
-+ {
-+ return 0; /* can't handle yet. */
-+// jmppattern = XVECEXP(jmppattern, 0, 0);
-+ }
-
- rtx jmpsrc = XEXP(jmppattern, 1);
- if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-@@ -708,19 +753,69 @@ bb_reg_rename (void)
-
- if (mask)
- {
-- int oldregno = bit2regno (def);
-+ int oldregno = bit2regno (toRename);
- int newregno = bit2regno (mask);
-- log ("bb_reg_rename %s -> %s (%d insns)\n", reg_names[oldregno], reg_names[newregno], found.size ());
-
-- for (std::set<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
-+ /* check the renamed insns. */
-+ std::vector<std::pair<rtx *, rtx>> locs;
-+ bool ok = true;
-+ std::vector<unsigned> patch;
-+ for (std::set<unsigned>::iterator i = found.begin (); ok && i != found.end (); ++i)
- {
--// if (be_verbose)
--// debug_rtx (insns[*i]);
-- do_reg_rename (PATTERN (insns[*i]), oldregno, newregno);
-+ rtx_insn * insn = insns[*i];
-+ validate_rename (locs, PATTERN (insn), oldregno, newregno);
-+
-+ if (!locs.empty ())
-+ {
-+ int num_clobbers_to_add = 0;
-+ int insn_code_number = recog (PATTERN (insn), insn, &num_clobbers_to_add);
-+ if (insn_code_number < 0 || !check_asm_operands (PATTERN (insn)))
-+ {
-+ fprintf (stderr, "renaming %d -> %d failed: ", oldregno, newregno);
-+ debug_rtx (insn);
-+ for (std::vector<std::pair<rtx *, rtx>>::iterator j = locs.begin (); j != locs.end (); ++j)
-+ {
-+ debug_rtx (*j->first);
-+ debug_rtx (j->second);
-+ }
-+ ok = false;
-+ }
-+
-+ for (std::vector<std::pair<rtx *, rtx>>::iterator j = locs.begin (); j != locs.end (); ++j)
-+ *j->first = j->second;
-+
-+ if (!ok)
-+ {
-+ fprintf (stderr, "restored: ", oldregno, newregno);
-+ debug_rtx (insn);
-+ for (std::vector<std::pair<rtx *, rtx>>::iterator j = locs.begin (); j != locs.end (); ++j)
-+ {
-+ debug_rtx (*j->first);
-+ debug_rtx (j->second);
-+ }
-+ }
-+ locs.clear ();
-+
-+ patch.push_back(*i);
-+ }
- }
-
-- cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
-- cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
-+ if (!ok)
-+ continue;
-+
-+ log ("bb_reg_rename %s -> %s (%d insns)\n", reg_names[oldregno], reg_names[newregno], patch.size ());
++ rtx reg = XEXP(x, 0);
++ if (!REG_P(reg))
++ return true;
+
-+ for (std::vector<unsigned>::iterator i = patch.begin (); i != patch.end (); ++i)
-+ {
-+ rtx_insn * insn = insns[*i];
-+ rtx pattern = PATTERN (insn);
-+ SET_INSN_DELETED(insn);
-+ do_reg_rename (&pattern, oldregno, newregno);
-+ emit_insn_after(pattern, insn);
++ return false;
+ }
-+
-+// cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
-+// cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
- return 1;
- }
- }
-@@ -1209,7 +1304,7 @@ commute_add_move (void)
-
- SET_INSN_DELETED(insn);
-
-- insn = emit_insn_before (newinsn, next);
-+ insn = emit_insn_before (PATTERN (newinsn), next);
-
- add_reg_note (next, REG_INC, reg1dst);
-
-@@ -1295,28 +1390,33 @@ const_cmp_to_sub (void)
- continue;
-
- int intval = -INTVAL(srcp);
-- if (intval < -8 || intval > 7)
-+ if (intval < -8 || intval > 7 || intval == 0)
- continue;
-
- enum machine_mode mode = GET_MODE(dstp);
-+ if (GET_MODE_SIZE(mode) > 4)
-+ continue;
-+
-+ // printf("mode size: %d\n", GET_MODE_SIZE(mode));
-+
- rtx reg = dstp == left ? right : left;
-- rtx plus = gen_rtx_PLUS(mode, reg, gen_rtx_CONST_INT (mode, intval));
-+ rtx plus = gen_rtx_PLUS(mode, copy_reg(reg, -1), gen_rtx_CONST_INT (mode, intval));
-
-- rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(reg, plus));
-+ rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(copy_reg(reg, -1), plus));
-
- int num_clobbers_to_add = 0;
- int insn_code_number = recog (PATTERN (neuprev), neuprev, &num_clobbers_to_add);
-- if (insn_code_number >= 0 && !check_asm_operands (PATTERN (neuprev)))
-+ if (insn_code_number < 0 || !check_asm_operands (PATTERN (neuprev)))
- continue;
-
- // also convert current statement to cmp #0, reg
- SET_INSN_DELETED(insn);
-- rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, reg, gen_rtx_CONST_INT(mode, 0)));
-+ rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, copy_reg(reg, -1), gen_rtx_CONST_INT(mode, 0)));
- insn = emit_insn_after (neu, prev);
- add_reg_note (insn, REG_DEAD, reg);
-
- SET_INSN_DELETED(prev);
-- prev = emit_insn_before (neuprev, insn);
-+ prev = emit_insn_before (PATTERN (neuprev), insn);
-
- log ("const_cmp_to_sub replaced reg-reg compare with sub\n");
-
-@@ -1537,7 +1637,7 @@ shrink_stack_frame (void)
- return 0;
-
- bool usea5 = false;
-- unsigned paramstart = 4;
-+ int paramstart = 4;
- int a5offset = 0;
-
- /*
-@@ -1696,6 +1796,9 @@ shrink_stack_frame (void)
- insn_info ii;
- for (unsigned i = 0; i < infos.size (); ++i)
- {
-+ if (proepilogue[i])
-+ continue;
-+
- insn_info & jj = infos[i];
- ii |= jj;
- }
-@@ -1914,8 +2017,6 @@ shrink_stack_frame (void)
- return 0;
- }
-
--extern class opt_pass * global_pass_regrename;
--
- namespace
- {
-
-@@ -2012,11 +2113,8 @@ namespace
- if (do_elim_dead_assign && elim_dead_assign ())
- done = 0, update_insns (), update_insn_infos ();
-
-- if (do_bb_reg_rename && ::global_pass_regrename)
-+ if (do_bb_reg_rename)
- {
--// class opt_pass * rr = ::global_pass_regrename->clone ();
--// rr->execute (0);
--
- while (bb_reg_rename ())
- {
- update_insns ();
-diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
-index c1ec46ad8d7f..1f488dc54544 100644
---- gcc/cfgbuild.c
-+++ gcc/cfgbuild.c
-@@ -55,6 +55,7 @@ inside_basic_block_p (const rtx_insn *insn)
- case DEBUG_INSN:
- return true;
-
-+ case DEBUG_IMPLICIT_PTR:
- case JUMP_TABLE_DATA:
- case BARRIER:
- case NOTE:
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index fad839f8f926..3d1e87af39fc 100755
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -1913,8 +1913,6 @@ regrename_optimize (void)
- return 0;
- }
-
--class opt_pass * global_pass_regrename;
--
- namespace {
-
- const pass_data pass_data_regrename =
-@@ -1935,7 +1933,6 @@ class pass_regrename : public rtl_opt_pass
- pass_regrename (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_regrename, ctxt)
- {
-- ::global_pass_regrename = this;
- }
-
- /* opt_pass methods: */
-
-From 7b2b67ccbe0e6ea8a226071a001cdeac5a493a1d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 22 Apr 2017 16:31:08 +0200
-Subject: [PATCH 077/303] @R restored original regrename.c, since no longer
- used with TARGET_AMIGA. Only left the fix for df
-
----
- gcc/regrename.c | 34 +++++++++++++++++-----------------
- 1 file changed, 17 insertions(+), 17 deletions(-)
-
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index 3d1e87af39fc..1ed6557ee713 100755
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -356,9 +356,8 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- {
- bool has_preferred_class;
- enum reg_class preferred_class;
-+ int pass;
- int best_new_reg = old_reg;
-- int new_reg;
-- int hit = 0;
-
- /* Further narrow the set of registers we can use for renaming.
- If the chain needs a call-saved register, mark the call-used
-@@ -371,14 +370,14 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
-
- /* Compute preferred rename class of super union of all the classes
- in the chain. */
-- preferred_class = (enum reg_class) targetm.preferred_rename_class2 (
-- super_class, old_reg);
-+ preferred_class
-+ = (enum reg_class) targetm.preferred_rename_class (super_class);
-
- /* Pick and check the register from the tied chain iff the tied chain
- is not renamed. */
- if (this_head->tied_chain && !this_head->tied_chain->renamed
-- && check_new_reg_p (old_reg, this_head->tied_chain->regno, this_head,
-- *unavailable))
-+ && check_new_reg_p (old_reg, this_head->tied_chain->regno,
-+ this_head, *unavailable))
- return this_head->tied_chain->regno;
-
- /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
-@@ -388,10 +387,14 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
- ascending order without any preference. */
- has_preferred_class = (preferred_class != NO_REGS);
-+ for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
-+ {
-+ int new_reg;
- for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
- {
- if (has_preferred_class
-- && !TEST_HARD_REG_BIT(reg_class_contents[preferred_class],
-+ && (pass == 0)
-+ != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
- new_reg))
- continue;
-
-@@ -405,11 +408,14 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- don't belong to PREFERRED_CLASS to registers that do, even
- though the latters were used not very long ago.
- Also use a register if no best_new_reg was found till now */
-- if (new_reg < old_reg || !hit)
-- {
-- hit = 1;
-+ if (((pass == 0 || !has_preferred_class)
-+ && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
-+ best_new_reg))
-+ || tick[best_new_reg] > tick[new_reg])
- best_new_reg = new_reg;
- }
-+ if (pass == 0 && best_new_reg != old_reg)
-+ break;
- }
- return best_new_reg;
- }
-@@ -1932,8 +1938,7 @@ class pass_regrename : public rtl_opt_pass
- public:
- pass_regrename (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_regrename, ctxt)
-- {
-- }
-+ {}
-
- /* opt_pass methods: */
- virtual bool gate (function *)
-@@ -1943,11 +1948,6 @@ class pass_regrename : public rtl_opt_pass
-
- virtual unsigned int execute (function *) { return regrename_optimize (); }
-
-- opt_pass * clone ()
-- {
-- return new pass_regrename(m_ctxt);
-- }
--
- }; // class pass_regrename
-
- } // anon namespace
-
-From 8425bbc011d5d94d7e2270c00b904da4170fc644 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 22 Apr 2017 19:54:50 +0200
-Subject: [PATCH 078/303] @B fix hard reg tracking in parallel insns, @I some
- cleanup
-
----
- gcc/bbb-opts.c | 144 ++++++++++++++++++++++++---------------------------------
- 1 file changed, 61 insertions(+), 83 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 1f70ffecc2d4..e7de83e59c07 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -26,9 +26,30 @@
- * #1 propagate_moves
- * check if a->b->a can be moved out of a loop.
- *
-- * #2 strcpy_opt
-+ * #2 strcpy
- * check if a temp reg can be eliminated.
- *
-+ * #3 const_comp_sub
-+ * convert a compare with int constant into sub statement.
-+ *
-+ * #4 merge_add
-+ * merge adds
-+ *
-+ * #5 elim_dead_assign
-+ * eliminate some dead assignments.
-+ *
-+ * #6 shrink stack frame
-+ * remove push/pop for unused variables
-+ *
-+ * #7 rename register
-+ * rename registers without breaking register parameters, inline asm etc.
-+ *
-+ * Lessons learned:
-+ *
-+ * - do not trust existing code, better delete insns and inster a new one.
-+ * - do not modify insns, create new insns from pattern
-+ * - do not reuse registers, create new reg rtx instances
-+ *
- */
-
- #include "config.h"
-@@ -55,10 +76,12 @@
- static bool be_verbose;
-
- extern struct lang_hooks lang_hooks;
-+
-+/* Lookup of the current function name. */
- extern tree current_function_decl;
- static tree last_function_decl;
- static char const *
--getCurrentFunctionName ()
-+get_current_function_name ()
- {
- static char fxname[512];
- if (current_function_decl == NULL)
-@@ -68,6 +91,7 @@ getCurrentFunctionName ()
- return fxname;
- }
-
-+/* a simple log to stdout. */
- static int
- log (char const * fmt, ...)
- {
-@@ -79,7 +103,7 @@ log (char const * fmt, ...)
- if (last_function_decl != current_function_decl)
- {
- last_function_decl = current_function_decl;
-- printf (":bbb: in '%s'\n", getCurrentFunctionName ());
-+ printf (":bbb: in '%s'\n", get_current_function_name ());
- }
- printf (":bbb: ");
- int retval = vprintf (fmt, args);
-@@ -88,7 +112,7 @@ log (char const * fmt, ...)
- return retval;
- }
-
--/* Enough for m68k.
-+/* Information for each insn to detect alive registers. Enough for m68k.
- * Why a class? Maybe extend it for general usage.
- *
- * Track use & def separate to determine starting points.
-@@ -220,6 +244,7 @@ struct insn_info
- void
- scan (rtx);
-
-+ /* return bits for alternate free registers. */
- unsigned
- get_free_mask () const
- {
-@@ -267,7 +292,7 @@ insn_info::scan (rtx x)
- scan (SET_DEST(x));
- if (REG_P(SET_DEST(x)))
- {
-- _def = _use;
-+ _def |= _use;
- _use = u;
- }
- scan (SET_SRC(x));
-@@ -288,12 +313,13 @@ insn_info::scan (rtx x)
- }
- }
-
-+/* create a copy for a reg. Optional specify a new register number. */
- static rtx
--copy_reg(rtx reg, int newregno)
-+copy_reg (rtx reg, int newregno)
- {
- if (newregno < 0)
- newregno = REGNO(reg);
-- rtx x = gen_raw_REG(GET_MODE(reg), newregno);
-+ rtx x = gen_raw_REG (GET_MODE(reg), newregno);
- x->jump = reg->jump;
- x->call = reg->call;
- x->unchanging = reg->unchanging;
-@@ -307,8 +333,9 @@ copy_reg(rtx reg, int newregno)
- return x;
- }
-
-+/* Rename the register plus track all locs to undo these changes. */
- static void
--validate_rename (std::vector<std::pair<rtx *, rtx>> & loc, rtx x, unsigned oldregno, unsigned newregno)
-+temp_reg_rename (std::vector<std::pair<rtx *, rtx>> & loc, rtx x, unsigned oldregno, unsigned newregno)
- {
- RTX_CODE code = GET_CODE(x);
-
-@@ -322,44 +349,17 @@ validate_rename (std::vector<std::pair<rtx *, rtx>> & loc, rtx x, unsigned oldre
- {
- if (REGNO(y) == oldregno)
- {
-- rtx z = copy_reg(y, newregno);
-+ rtx z = copy_reg (y, newregno);
- loc.push_back (std::make_pair (&XEXP(x, i), y));
- XEXP(x, i) = z;
- }
- }
- else
-- validate_rename (loc, y, oldregno, newregno);
-+ temp_reg_rename (loc, y, oldregno, newregno);
- }
- else if (fmt[i] == 'E')
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-- validate_rename (loc, XVECEXP(x, i, j), oldregno, newregno);
-- }
--}
--
--/* perform reg renaming. */
--static void
--do_reg_rename (rtx * loc, unsigned oldregno, unsigned newregno)
--{
-- rtx x = *loc;
-- if (REG_P(x))
-- {
-- if (REGNO(x) == oldregno)
-- *loc = copy_reg(x, newregno);
-- return;
-- }
--
-- if (x == cc0_rtx)
-- return;
--
-- RTX_CODE code = GET_CODE(x);
-- const char *fmt = GET_RTX_FORMAT(code);
-- for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-- {
-- if (fmt[i] == 'e')
-- do_reg_rename (&XEXP(x, i), oldregno, newregno);
-- else if (fmt[i] == 'E')
-- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-- do_reg_rename (&XVECEXP(x, i, j), oldregno, newregno);
-+ temp_reg_rename (loc, XVECEXP(x, i, j), oldregno, newregno);
- }
- }
-
-@@ -758,64 +758,42 @@ bb_reg_rename (void)
-
- /* check the renamed insns. */
- std::vector<std::pair<rtx *, rtx>> locs;
-+ std::vector<std::pair<rtx *, rtx>> patch;
- bool ok = true;
-- std::vector<unsigned> patch;
-+
- for (std::set<unsigned>::iterator i = found.begin (); ok && i != found.end (); ++i)
- {
- rtx_insn * insn = insns[*i];
-- validate_rename (locs, PATTERN (insn), oldregno, newregno);
-
-+ /* temp rename. */
-+ temp_reg_rename (locs, PATTERN (insn), oldregno, newregno);
- if (!locs.empty ())
- {
- int num_clobbers_to_add = 0;
- int insn_code_number = recog (PATTERN (insn), insn, &num_clobbers_to_add);
- if (insn_code_number < 0 || !check_asm_operands (PATTERN (insn)))
-- {
-- fprintf (stderr, "renaming %d -> %d failed: ", oldregno, newregno);
-- debug_rtx (insn);
-- for (std::vector<std::pair<rtx *, rtx>>::iterator j = locs.begin (); j != locs.end (); ++j)
-- {
-- debug_rtx (*j->first);
-- debug_rtx (j->second);
-- }
-- ok = false;
-- }
-+ ok = false;
-
-+ /* undo temp change but keep loc and new register. */
- for (std::vector<std::pair<rtx *, rtx>>::iterator j = locs.begin (); j != locs.end (); ++j)
-- *j->first = j->second;
--
-- if (!ok)
- {
-- fprintf (stderr, "restored: ", oldregno, newregno);
-- debug_rtx (insn);
-- for (std::vector<std::pair<rtx *, rtx>>::iterator j = locs.begin (); j != locs.end (); ++j)
-- {
-- debug_rtx (*j->first);
-- debug_rtx (j->second);
-- }
-+ patch.push_back (std::make_pair (j->first, *j->first));
-+ *j->first = j->second;
- }
-- locs.clear ();
-
-- patch.push_back(*i);
-+ locs.clear ();
- }
- }
-
- if (!ok)
- continue;
-
-- log ("bb_reg_rename %s -> %s (%d insns)\n", reg_names[oldregno], reg_names[newregno], patch.size ());
-+ log ("bb_reg_rename %s -> %s (%d locs)\n", reg_names[oldregno], reg_names[newregno], patch.size ());
-
-- for (std::vector<unsigned>::iterator i = patch.begin (); i != patch.end (); ++i)
-- {
-- rtx_insn * insn = insns[*i];
-- rtx pattern = PATTERN (insn);
-- SET_INSN_DELETED(insn);
-- do_reg_rename (&pattern, oldregno, newregno);
-- emit_insn_after(pattern, insn);
-- }
-+ /* apply all changes. */
-+ for (std::vector<std::pair<rtx *, rtx>>::iterator j = patch.begin (); j != patch.end (); ++j)
-+ *j->first = j->second;
-
--// cselib_invalidate_rtx (gen_raw_REG (SImode, oldregno));
--// cselib_invalidate_rtx (gen_raw_REG (SImode, newregno));
- return 1;
- }
- }
-@@ -879,7 +857,7 @@ bb_reg_rename (void)
- * The label must only be reachable by the exit jump.
- */
- static unsigned
--propagate_moves ()
-+opt_propagate_moves ()
- {
- unsigned change_count = 0;
- rtx_insn * current_label = 0;
-@@ -1341,7 +1319,7 @@ commute_add_move (void)
- *
- */
- static unsigned
--const_cmp_to_sub (void)
-+opt_const_cmp_to_sub (void)
- {
- unsigned change_count = 0;
- #if HAVE_cc0
-@@ -1400,9 +1378,9 @@ const_cmp_to_sub (void)
- // printf("mode size: %d\n", GET_MODE_SIZE(mode));
-
- rtx reg = dstp == left ? right : left;
-- rtx plus = gen_rtx_PLUS(mode, copy_reg(reg, -1), gen_rtx_CONST_INT (mode, intval));
-+ rtx plus = gen_rtx_PLUS(mode, copy_reg (reg, -1), gen_rtx_CONST_INT (mode, intval));
-
-- rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(copy_reg(reg, -1), plus));
-+ rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(copy_reg (reg, -1), plus));
-
- int num_clobbers_to_add = 0;
- int insn_code_number = recog (PATTERN (neuprev), neuprev, &num_clobbers_to_add);
-@@ -1532,7 +1510,7 @@ elim_dead_assign (void)
- add.l d1,a1
- */
- static unsigned
--merge_add (void)
-+opt_merge_add (void)
- {
- unsigned change_count = 0;
- for (unsigned index = 0; index + 2 < insns.size (); ++index)
-@@ -1623,7 +1601,7 @@ clear_temp ()
- * newstartvalue = startvalue - omitted pushes
- */
- static unsigned
--shrink_stack_frame (void)
-+opt_shrink_stack_frame (void)
- {
- /* nothing to do. */
- if (!insns.size ())
-@@ -2100,14 +2078,14 @@ namespace
- if (do_commute_add_move && commute_add_move ())
- done = 0, update_insns ();
-
-- if (do_propagate_moves && propagate_moves ())
-+ if (do_propagate_moves && opt_propagate_moves ())
- done = 0, update_insns ();
-
- update_insn_infos ();
-- if (do_const_cmp_to_sub && const_cmp_to_sub ())
-+ if (do_const_cmp_to_sub && opt_const_cmp_to_sub ())
- done = 0, update_insns (), update_insn_infos ();
-
-- if (do_merge_add && merge_add ())
-+ if (do_merge_add && opt_merge_add ())
- done = 0, update_insns (), update_insn_infos ();
-
- if (do_elim_dead_assign && elim_dead_assign ())
-@@ -2129,7 +2107,7 @@ namespace
-
- if (do_shrink_stack_frame)
- {
-- shrink_stack_frame ();
-+ opt_shrink_stack_frame ();
- update_insns ();
- update_insn_infos ();
- }
-
-From cfd147a3142a4e1b6495f4f1c57d2b236c991c95 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 00:05:15 +0200
-Subject: [PATCH 079/303] @N shrink-stack-frame is now also dropping unused
- frame pointers. @I more cleanup
-
----
- gcc/bbb-opts.c | 115 +++++++++++++++++++++++++++++++++++----------------------
- 1 file changed, 70 insertions(+), 45 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index e7de83e59c07..d684e280a17e 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -367,7 +367,7 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx>> & loc, rtx x, unsigned oldre
- * Collect some data.
- */
- static std::vector<rtx_insn *> insns;
--static std::vector<bool> proepilogue;
-+static std::vector<char> proepilogue;
- static std::vector<rtx_insn *> temp;
- static std::vector<rtx_insn *> jumps;
- static std::map<rtx_insn *, unsigned> insn2index;
-@@ -477,7 +477,7 @@ update_insns ()
-
- df_insn_rescan_all ();
-
-- bool inproepilogue = true;
-+ char inproepilogue = 1;
- /* create a vector with relevant insn. */
- for (insn = get_insns (); insn; insn = next)
- {
-@@ -493,32 +493,34 @@ update_insns ()
- proepilogue.push_back (inproepilogue);
-
- if (JUMP_P(insn))
-- inproepilogue = false;
-+ inproepilogue = 0;
- }
-
- if (NOTE_P(insn))
- {
- if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-- inproepilogue = false;
-+ inproepilogue = 0;
- else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
-- inproepilogue = true;
-+ inproepilogue = 2;
- }
- }
- }
-
-+/* This is the important function to track register usage plus hard/live state.
-+ *
-+ * Start at bottom and work upwards. On all labels trigger all jumps referring to this label.
-+ * A set destination into a register is a def. All other register references are an use.
-+ * Hard registers cann't be renamed and are mandatory for regparms and asm_operands.
-+ */
- static void
- update_insn_infos (void)
- {
- /* prepare insn_info */
-- insn_info ii0;
-- for (unsigned i = 0; i < insns.size (); ++i)
-- {
-- infos.push_back (ii0);
-- }
-+ infos.resize (insns.size ());
-
- /* own analyze reg life */
- std::vector<std::pair<unsigned, insn_info>> todo;
-- todo.push_back (std::make_pair (insns.size () - 1, ii0));
-+ todo.push_back (std::make_pair (insns.size () - 1, insn_info ()));
-
- int pass = 0;
- while (!todo.empty ())
-@@ -531,9 +533,11 @@ update_insn_infos (void)
- for (int pos = p.first; pos >= 0; --pos)
- {
- rtx_insn * insn = insns[pos];
-- if (!insn) // moved to temp for stack frame cleanup
-+ /* can be NULL as used in opt_shrink_stack_frame(). */
-+ if (!insn)
- continue;
-
-+ /* no new information -> break. */
- if (pass && infos[pos].contains (ii))
- break;
-
-@@ -648,6 +652,7 @@ update_insn_infos (void)
- }
- }
-
-+/* convert the lowest set bit into a register number. */
- static int
- bit2regno (unsigned bit)
- {
-@@ -667,7 +672,7 @@ bit2regno (unsigned bit)
- * Always prefer lower register numbers within the class.
- */
- static unsigned
--bb_reg_rename (void)
-+opt_reg_rename (void)
- {
- // dump_insns ("rename", 1);
- for (unsigned index = 0; index < insns.size (); ++index)
-@@ -738,8 +743,7 @@ bb_reg_rename (void)
- rtx jmppattern = PATTERN (insn);
- if (GET_CODE(jmppattern) == PARALLEL)
- {
-- return 0; /* can't handle yet. */
--// jmppattern = XVECEXP(jmppattern, 0, 0);
-+ return 0; /* can't handle yet. Abort renaming. */
- }
-
- rtx jmpsrc = XEXP(jmppattern, 1);
-@@ -788,7 +792,7 @@ bb_reg_rename (void)
- if (!ok)
- continue;
-
-- log ("bb_reg_rename %s -> %s (%d locs)\n", reg_names[oldregno], reg_names[newregno], patch.size ());
-+ log ("opt_reg_rename %s -> %s (%d locs)\n", reg_names[oldregno], reg_names[newregno], patch.size ());
-
- /* apply all changes. */
- for (std::vector<std::pair<rtx *, rtx>>::iterator j = patch.begin (); j != patch.end (); ++j)
-@@ -1470,6 +1474,10 @@ opt_const_cmp_to_sub (void)
- return change_count;
- }
-
-+/*
-+ * Some optimizations (e.g. propagate_moves) might result into an unuses assignment behind the loop.
-+ * delete those insns.
-+ */
- static unsigned
- elim_dead_assign (void)
- {
-@@ -1570,6 +1578,9 @@ opt_merge_add (void)
- return change_count;
- }
-
-+/*
-+ * Move the insns back from temp to insns.
-+ */
- static void
- clear_temp ()
- {
-@@ -1607,6 +1618,7 @@ opt_shrink_stack_frame (void)
- if (!insns.size ())
- return 0;
-
-+ std::vector<int> a5pos;
- temp.resize (insns.size ());
-
- unsigned pos = 0;
-@@ -1622,16 +1634,11 @@ opt_shrink_stack_frame (void)
- * Move prologue to temp.
- * Only register push and parallel insn unless its a link a5 are moved.
- */
-- rtx_insn * prev = get_insns ();
- for (; pos < insns.size ();)
- {
- insn = insns[pos];
-
-- /* check for prologue end. */
-- for (; prev != insn; prev = NEXT_INSN (prev))
-- if (NOTE_P(prev) && NOTE_KIND(prev) == NOTE_INSN_PROLOGUE_END)
-- break;
-- if (prev != insn)
-+ if (proepilogue[pos] != 1)
- break;
-
- rtx pattern = PATTERN (insn);
-@@ -1642,6 +1649,7 @@ opt_shrink_stack_frame (void)
- /* ignore link a5 */
- if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
- {
-+ a5pos.push_back (pos);
- usea5 = true;
- set = XVECEXP(pattern, 0, 2);
- a5offset = INTVAL(XEXP(SET_SRC(set), 1));
-@@ -1657,6 +1665,9 @@ opt_shrink_stack_frame (void)
- }
- if (GET_CODE(pattern) != SET)
- {
-+ /* (set (mem:BLK (scratch) [0 A8]) (unspec:BLK [ ...)) */
-+ if (MEM_P(SET_DEST(pattern)) && GET_CODE(SET_SRC(pattern)) == UNSPEC)
-+ a5pos.push_back (pos);
- ++pos;
- continue;
- }
-@@ -1701,21 +1712,13 @@ opt_shrink_stack_frame (void)
-
- unsigned prologueend = pos;
-
-- prev = insn;
--
- /* search epilogues - there can be multiple epilogues. */
- while (pos < insns.size ())
- {
- while (pos < insns.size ())
- {
-- insn = insns[pos];
-- for (; prev != insn; prev = NEXT_INSN (prev))
-- if (NOTE_P(prev) && NOTE_KIND(prev) == NOTE_INSN_EPILOGUE_BEG)
-- break;
--
-- if (prev != insn)
-+ if (proepilogue[pos])
- break;
--
- ++pos;
- }
-
-@@ -1723,13 +1726,10 @@ opt_shrink_stack_frame (void)
- for (; pos < insns.size (); ++pos)
- {
- insn = insns[pos];
-- if (JUMP_P(insn)) /* return */
-- break;
--
-- if (LABEL_P(insn))
-+ if (JUMP_P(insn) || LABEL_P(insn) || !proepilogue[pos])
- break;
-
-- /* omitt the frame pointer a5. */
-+ /* omit the frame pointer a5. */
- rtx pattern = PATTERN (insn);
- if (GET_CODE(pattern) == PARALLEL)
- {
-@@ -1737,7 +1737,10 @@ opt_shrink_stack_frame (void)
- rtx dst = SET_DEST(set);
- /* unlink is last. */
- if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-- break;
-+ {
-+ a5pos.push_back (pos);
-+ break;
-+ }
-
- /* movem. */
- temp[pos] = insn;
-@@ -1766,7 +1769,6 @@ opt_shrink_stack_frame (void)
- }
- }
- }
-- prev = insn;
- ++pos;
- }
- /* gather usage stats without prologue/epilogue */
-@@ -1989,6 +1991,33 @@ opt_shrink_stack_frame (void)
- }
- }
-
-+ if (usea5 && a5offset == -4)
-+ {
-+ for (std::vector<int>::iterator i = a5pos.begin (); i != a5pos.end (); ++i)
-+ {
-+ temp[*i] = insns[*i];
-+ insns[*i] = 0;
-+ }
-+ update_insn_infos ();
-+ insn_info ii;
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ if (proepilogue[i])
-+ continue;
-+
-+ insn_info & jj = infos[i];
-+ ii |= jj;
+ }
-+ unsigned freemask = ~ii._use;
+
-+ if (freemask & (1 << FRAME_POINTER_REGNUM))
-+ {
-+ log ("dropping unused frame pointer\n");
-+ for (std::vector<int>::iterator i = a5pos.begin (); i != a5pos.end (); ++i)
-+ SET_INSN_DELETED(temp[*i]);
-+ }
++ if (GET_CODE(op) == UNSPEC)
++ return false;
+ }
+
- /* restore stack insns */
- clear_temp ();
-
-@@ -2000,14 +2029,14 @@ namespace
-
- const pass_data pass_data_bbb_optimizations =
- { RTL_PASS, /* type */
-- "bbb", /* name */
-+ "bebbo's-optimizers", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
-- ( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ 0, /* todo_flags_finish */
- };
-
- class pass_bbb_optimizations : public rtl_opt_pass
-@@ -2053,10 +2082,6 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
-- df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
-- df_note_add_problem ();
-- df_analyze ();
--
- be_verbose = strchr (string_bbb_opts, 'v');
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
-@@ -2093,7 +2118,7 @@ namespace
-
- if (do_bb_reg_rename)
- {
-- while (bb_reg_rename ())
-+ while (opt_reg_rename ())
- {
- update_insns ();
- update_insn_infos ();
-
-From 0461e994f5f13ef6becd36265f33fa8812f25cb3 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 00:12:10 +0200
-Subject: [PATCH 080/303] @V bump version
-
----
- gcc/BASE-VER | 2 +-
- gcc/DATESTAMP | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/BASE-VER b/gcc/BASE-VER
-index 6352d5267189..91eb9361dcd3 100644
---- gcc/BASE-VER
-+++ gcc/BASE-VER
-@@ -1 +1 @@
--6.3.1b
-+6.3.1c
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index e30948e24831..e9793b647365 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170320
-+20170423
-
-From 7cf932893a3328d06b1c1eb4c51b9eaf39db8bc1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 10:57:09 +0200
-Subject: [PATCH 081/303] @B some fixes in opt_reg_rename
-
----
- gcc/bbb-opts.c | 23 +++++++++++++----------
- 1 file changed, 13 insertions(+), 10 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index d684e280a17e..a8122e80998e 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -238,6 +238,8 @@ struct insn_info
- return false;
- if (o._use & ~_use)
- return false;
-+ if (o._hard & ~_hard)
-+ return false;
- return true;
- }
-
-@@ -298,7 +300,7 @@ insn_info::scan (rtx x)
- scan (SET_SRC(x));
- int code = GET_CODE(SET_SRC(x));
- if (code == ASM_OPERANDS)
-- _hard |= _def | _use;
-+ _use = _hard |= _def | _use;
- return;
- }
-
-@@ -713,16 +715,13 @@ opt_reg_rename (void)
-
- insn_info & jj = infos[pos];
-
-- /* not used. */
-- if (!(jj._use & toRename))
-- continue;
--
- /* marked as hard reg -> invalid rename */
- if (jj._hard & toRename)
-- {
-- mask = 0;
-- break;
-- }
-+ mask = 0;
-+
-+ /* defined again -> invalid rename */
-+ if (jj._def & toRename)
-+ mask = 0;
-
- /* update free regs. */
- mask &= ~jj._use;
-@@ -730,6 +729,10 @@ opt_reg_rename (void)
- if (!mask)
- break;
-
-+ /* not used. */
-+ if (!(jj._use & toRename))
-+ continue;
-+
- found.insert (pos);
-
- /* follow jump and/or next insn. */
-@@ -1902,7 +1905,7 @@ opt_shrink_stack_frame (void)
- else
- {
- /* pop */
-- if (usea5)
-+ if (usea5 && a5offset != -4)
- {
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
-
-From fbc0890125f5455fbd9947d439f0caab8b0a4e12 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 10:59:12 +0200
-Subject: [PATCH 082/303] @R change template >> to > > for crappy compilers
-
----
- gcc/bbb-opts.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index a8122e80998e..90751c4165d3 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -337,7 +337,7 @@ copy_reg (rtx reg, int newregno)
-
- /* Rename the register plus track all locs to undo these changes. */
- static void
--temp_reg_rename (std::vector<std::pair<rtx *, rtx>> & loc, rtx x, unsigned oldregno, unsigned newregno)
-+temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldregno, unsigned newregno)
- {
- RTX_CODE code = GET_CODE(x);
-
-@@ -521,7 +521,7 @@ update_insn_infos (void)
- infos.resize (insns.size ());
-
- /* own analyze reg life */
-- std::vector<std::pair<unsigned, insn_info>> todo;
-+ std::vector<std::pair<unsigned, insn_info> > todo;
- todo.push_back (std::make_pair (insns.size () - 1, insn_info ()));
-
- int pass = 0;
-@@ -764,8 +764,8 @@ opt_reg_rename (void)
- int newregno = bit2regno (mask);
-
- /* check the renamed insns. */
-- std::vector<std::pair<rtx *, rtx>> locs;
-- std::vector<std::pair<rtx *, rtx>> patch;
-+ std::vector<std::pair<rtx *, rtx> > locs;
-+ std::vector<std::pair<rtx *, rtx> > patch;
- bool ok = true;
-
- for (std::set<unsigned>::iterator i = found.begin (); ok && i != found.end (); ++i)
-@@ -782,7 +782,7 @@ opt_reg_rename (void)
- ok = false;
-
- /* undo temp change but keep loc and new register. */
-- for (std::vector<std::pair<rtx *, rtx>>::iterator j = locs.begin (); j != locs.end (); ++j)
-+ for (std::vector<std::pair<rtx *, rtx> >::iterator j = locs.begin (); j != locs.end (); ++j)
- {
- patch.push_back (std::make_pair (j->first, *j->first));
- *j->first = j->second;
-@@ -798,7 +798,7 @@ opt_reg_rename (void)
- log ("opt_reg_rename %s -> %s (%d locs)\n", reg_names[oldregno], reg_names[newregno], patch.size ());
-
- /* apply all changes. */
-- for (std::vector<std::pair<rtx *, rtx>>::iterator j = patch.begin (); j != patch.end (); ++j)
-+ for (std::vector<std::pair<rtx *, rtx> >::iterator j = patch.begin (); j != patch.end (); ++j)
- *j->first = j->second;
-
- return 1;
-
-From d98fb77f2e7d620cb8c901f806e8d938b3e7f07f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 13:38:06 +0200
-Subject: [PATCH 083/303] @B init insn_infos before running opt_strcpy
-
----
- gcc/bbb-opts.c | 35 +++++++++++++++++++----------------
- 1 file changed, 19 insertions(+), 16 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 90751c4165d3..2858daa6c908 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -390,24 +390,23 @@ clear (void)
-
- /*
- * return true if the register is DEAD.
-+ * Do not check at jumps.
- */
- static bool
--is_reg_dead (unsigned regno, unsigned pos)
-+is_reg_dead (unsigned regno, unsigned _pos)
- {
-- for (;;)
-+ // skip labels.
-+ for (unsigned pos = _pos + 1; pos < infos.size (); ++pos)
- {
-- if (pos + 1 >= infos.size ())
-- return true;
-+ insn_info & ii0 = infos[pos];
-+ // skip entries without info
-+ if (!ii0._def && !ii0._use && !ii0._hard)
-+ continue;
-
-- rtx_insn * insn = insns[pos + 1];
-- if (!LABEL_P(insn) && GET_CODE(insn) != USE)
-- break;
-- ++pos;
-+ // not dead if usage is reported in the next statement
-+ return !ii0.is_use (regno) && !ii0.is_hard (regno);
- }
--
-- insn_info & ii0 = infos[pos + 1];
-- // not dead if usage is reported in the next statement
-- return !ii0.is_use (regno);
+ return true;
- }
-
- /*
-@@ -720,12 +719,9 @@ opt_reg_rename (void)
- mask = 0;
-
- /* defined again -> invalid rename */
-- if (jj._def & toRename)
-+ if ((jj._def & toRename) && !(jj._use & toRename))
- mask = 0;
-
-- /* update free regs. */
-- mask &= ~jj._use;
-- mask &= ~jj._def;
- if (!mask)
- break;
-
-@@ -733,6 +729,12 @@ opt_reg_rename (void)
- if (!(jj._use & toRename))
- continue;
-
-+ /* update free regs. */
-+ mask &= ~jj._use;
-+ mask &= ~jj._def;
-+ if (!mask)
-+ break;
-+
- found.insert (pos);
-
- /* follow jump and/or next insn. */
-@@ -2100,6 +2102,7 @@ namespace
- {
- int done = 1;
- update_insns ();
-+ update_insn_infos ();
- if (do_opt_strcpy && opt_strcpy ())
- done = 0, update_insns ();
-
-
-From 78db2bc90ad5701e59107a782343b1d25937102e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 23:08:07 +0200
-Subject: [PATCH 084/303] @B fix regparm with return values > 64bit
-
----
- gcc/config/m68k/amigaos.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index dd5707612119..d385ab1ff108 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -435,6 +435,15 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- if (!next_param && TREE_VALUE (param) != void_type_node)
- cum->num_of_regs = 0;
- }
-+
-+ /* check for return values passed in a0 */
-+ if (cum->num_of_regs)
-+ {
-+ tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-+ int sz = type ? TREE_INT_CST_LOW(type) : 0;
-+ if (sz > 64) /* mark a0 as already used. */
-+ cum->regs_already_used |= 1<<8;
-+ }
- }
-
- //#if ! defined (PCC_STATIC_STRUCT_RETURN) && defined (M68K_STRUCT_VALUE_REGNUM)
-
-From 5c0207b6ae6544541c786c74d57ddfcbe48b7a48 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 23:08:48 +0200
-Subject: [PATCH 085/303] @B fix __regards definition
-
----
- gcc/config/m68k/m68kamigaos.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 68f3277bd87c..20e0b66face2 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -194,7 +194,7 @@ amiga_declare_object = 0
- builtin_define ("__saveds=__attribute__((__saveds__))"); \
- builtin_define ("__interrupt=__attribute__((__interrupt__))"); \
- builtin_define ("__stackext=__attribute__((__stackext__))"); \
-- builtin_define ("__regargs=__attribute__((__regparm__))"); \
-+ builtin_define ("__regargs=__attribute__((__regparm__(2)))"); \
- builtin_define ("__stdargs=__attribute__((__stkparm__))"); \
- builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \
- builtin_define_std ("amiga"); \
-
-From 827a96ae044a2b7925972b04ec8e24c0999daa71 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 23 Apr 2017 23:09:27 +0200
-Subject: [PATCH 086/303] @B fix return val sizes and so...
-
----
- gcc/bbb-opts.c | 55 +++++++++++++++++++++++++++++++++++++------------------
- 1 file changed, 37 insertions(+), 18 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 2858daa6c908..d0288f254f9c 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -476,7 +476,7 @@ update_insns ()
- rtx_insn *insn, *next;
- clear ();
-
-- df_insn_rescan_all ();
-+ // df_insn_rescan_all ();
-
- char inproepilogue = 1;
- /* create a vector with relevant insn. */
-@@ -593,10 +593,25 @@ update_insn_infos (void)
-
- if (JUMP_P(insn))
- {
-+ insn_info use;
- if (ANY_RETURN_P(pattern))
-- ii.reset ();
-+ {
-+ tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-+ int sz = type ? TREE_INT_CST_LOW(type) : 0;
-+ // log ("return size %d\n", sz);
-+ if (sz <= 64)
-+ {
-+ use.hard (0);
-+ use.use (0);
-+ if (sz > 32)
-+ {
-+ use.hard (1);
-+ use.use (1);
-+ }
-+ }
-+ ii.reset ();
-+ }
-
-- insn_info use;
- use.scan (pattern);
- infos[pos] = use | ii;
- ii.updateWith (use);
-@@ -752,7 +767,7 @@ opt_reg_rename (void)
- }
-
- rtx jmpsrc = XEXP(jmppattern, 1);
-- if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-+ if (jmpsrc && GET_CODE(jmpsrc) == IF_THEN_ELSE)
- if (pos + 1 < insns.size ())
- todo.push_back (pos + 1);
- }
-@@ -1065,8 +1080,8 @@ opt_propagate_moves ()
- j = reg_reg.end ();
- inc = false;
-
-- df_insn_rescan (newii);
-- df_insn_rescan (newjj);
-+ // df_insn_rescan (newii);
-+ // df_insn_rescan (newjj);
-
- /* add fixes if there were jumps out of the loop. */
- if (jump_out.size ())
-@@ -1078,7 +1093,7 @@ opt_propagate_moves ()
- rtx neu = gen_rtx_SET(
- dstj, gen_rtx_PLUS(Pmode, dsti, gen_rtx_CONST_INT(Pmode, fixups[k])));
- rtx_insn * neui = emit_insn_after (neu, jump_out[k]);
-- df_insn_rescan (neui);
-+ // df_insn_rescan (neui);
- }
- }
- ++change_count;
-@@ -1178,7 +1193,7 @@ opt_strcpy ()
- SET_INSN_DELETED(x2reg);
- SET_INSN_DELETED(insn);
-
-- df_insn_rescan (reg2x);
-+ // df_insn_rescan (reg2x);
-
- ++change_count;
- }
-@@ -1238,7 +1253,7 @@ opt_strcpy ()
- (nil)))
- */
- static unsigned
--commute_add_move (void)
-+opt_commute_add_move (void)
- {
- unsigned change_count = 0;
-
-@@ -1295,8 +1310,8 @@ commute_add_move (void)
-
- add_reg_note (next, REG_INC, reg1dst);
-
-- df_insn_rescan (insn);
-- df_insn_rescan (next);
-+ // df_insn_rescan (insn);
-+ // df_insn_rescan (next);
-
- ++change_count;
- }
-@@ -1484,7 +1499,7 @@ opt_const_cmp_to_sub (void)
- * delete those insns.
- */
- static unsigned
--elim_dead_assign (void)
-+opt_elim_dead_assign (void)
- {
- unsigned change_count = 0;
- for (unsigned index = 0; index + 1 < insns.size (); ++index)
-@@ -1835,7 +1850,7 @@ opt_shrink_stack_frame (void)
- adjust += 4;
- }
- else
-- regs.push_back (reg);
-+ regs.push_back (copy_reg (reg, -1));
- }
-
- /* don't touch - clobbers! */
-@@ -1907,7 +1922,7 @@ opt_shrink_stack_frame (void)
- else
- {
- /* pop */
-- if (usea5 && a5offset != -4)
-+ if (usea5)
- {
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
-@@ -2041,8 +2056,8 @@ namespace
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
-- 0, /* todo_flags_finish */
-- };
-+ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ };
-
- class pass_bbb_optimizations : public rtl_opt_pass
- {
-@@ -2087,6 +2102,10 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
-+ // df_set_flags (df_LR_RUN_DCE + df_DEFER_INSN_RESCAN);
-+ // df_note_add_problem ();
-+ // df_analyze ();
++}
+
- be_verbose = strchr (string_bbb_opts, 'v');
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
-@@ -2106,7 +2125,7 @@ namespace
- if (do_opt_strcpy && opt_strcpy ())
- done = 0, update_insns ();
-
-- if (do_commute_add_move && commute_add_move ())
-+ if (do_commute_add_move && opt_commute_add_move ())
- done = 0, update_insns ();
-
- if (do_propagate_moves && opt_propagate_moves ())
-@@ -2119,7 +2138,7 @@ namespace
- if (do_merge_add && opt_merge_add ())
- done = 0, update_insns (), update_insn_infos ();
-
-- if (do_elim_dead_assign && elim_dead_assign ())
-+ if (do_elim_dead_assign && opt_elim_dead_assign ())
- done = 0, update_insns (), update_insn_infos ();
-
- if (do_bb_reg_rename)
-
-From e0bc074377aadb67fd623bd92a28c6938a53c557 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 24 Apr 2017 01:07:46 +0200
-Subject: [PATCH 087/303] @B fix mregparm for function pointer calls
-
----
- gcc/config/m68k/amigaos.c | 569 +++++++++++++++++++++++-----------------------
- 1 file changed, 280 insertions(+), 289 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index d385ab1ff108..c93188a3e90d 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -1,25 +1,25 @@
- /* 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).
-+ 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.
-+ 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 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.
-+ 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. */
-+ 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
- #define REGPARMS_68K 1
-@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */
- #include "tm_p.h"
- #include "target.h"
- #include "diagnostic-core.h"
-+#include "langhooks.h"
- #include "config/m68k/amigaos.h"
-
- //#define MYDEBUG 1
-@@ -56,28 +57,28 @@ 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.
-+ so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true.
-
-- This function is used in base relative code generation. */
-+ This function is used in base relative code generation. */
-
- int
- read_only_operand (rtx operand)
--{
-- if (GET_CODE (operand) == CONST)
-+ {
-+ if (GET_CODE (operand) == CONST)
- operand = XEXP (XEXP (operand, 0), 0);
-- if (GET_CODE (operand) == SYMBOL_REF)
-+ if (GET_CODE (operand) == SYMBOL_REF)
- return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
-- return 1;
--}
-+ return 1;
-+ }
-
- /* Choose the section to use for DECL. RELOC is true if its value contains
-- any relocatable expression. */
-+ any relocatable expression. */
-
- void
- amigaos_select_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED,
-- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
--{
-- // if (TREE_CODE (decl) == STRING_CST)
-+ 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
-@@ -104,195 +105,189 @@ amigaos_select_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED,
- // 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. */
-+ 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)
-+ {
-+ tree type = TREE_TYPE (decl);
-+ if (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
-- return (TREE_INT_CST_ELT(TYPE_SIZE (type), 1) == 0
-- && TREE_INT_CST_LOW (TYPE_SIZE (type)) < 32)
-- || FLOAT_TYPE_P (type);
--}
-+ return (TREE_INT_CST_ELT(TYPE_SIZE (type), 1) == 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);
-+ {
-+ 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 ((MEM_READONLY_P (rtl) && !MEM_VOLATILE_P (rtl)
-- && (flag_pic<3 || (TREE_CODE (decl) == STRING_CST
-- )
-- || amigaos_put_in_text (decl)))
-- || (TREE_CODE (decl) == VAR_DECL
-- && DECL_SECTION_NAME (decl) != NULL))
-- 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 ((MEM_READONLY_P (rtl) && !MEM_VOLATILE_P (rtl)
-+ && (flag_pic<3 || (TREE_CODE (decl) == STRING_CST
-+ )
-+ || amigaos_put_in_text (decl)))
-+ || (TREE_CODE (decl) == VAR_DECL
-+ && DECL_SECTION_NAME (decl) != NULL))
-+ 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)))));
--}
-+ {
-+ 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)
-+ {
-+ 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))))
-+ 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. */
-+ 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))
-+ tree args ATTRIBUTE_UNUSED,
-+ int flags ATTRIBUTE_UNUSED,
-+ bool *no_add_attrs)
++void
++amigaos_restore_a4 (void)
+ {
-+ if (TREE_CODE (*node) == VAR_DECL)
++ if (flag_pic >= 3 && !flag_resident)
+ {
-+ if (is_attribute_p ("chip", name))
- #ifdef TARGET_ASM_NAMED_SECTION
-- {
-- if (! TREE_STATIC (*node) && ! DECL_EXTERNAL (*node))
++ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
++ tree attr = lookup_attribute ("saveds", attrs);
++ if (attr || TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4)
+ {
-+ 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
-+ {
-+ /* 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");
-+ }
-+ }
++ rtx a4 = gen_rtx_ASM_INPUT_loc(VOIDmode, "\tlea ___a4_init,a4", DECL_SOURCE_LOCATION (current_function_decl));
++ a4->volatil = 1;
++ emit_insn(a4);
+ }
- #else
-- error ("`chip' attribute is not supported for this target");
-+ error ("`chip' attribute is not supported for this target");
- #endif
-- }
-- else
-- {
-- warning (OPT_Wattributes, "`%s' attribute only applies to variables",
-- IDENTIFIER_POINTER (name));
-- *no_add_attrs = true;
-- }
-+ }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to variables",
-+ IDENTIFIER_POINTER (name));
-+ *no_add_attrs = true;
-+ }
-
-- return NULL_TREE;
--}
-+ return NULL_TREE;
-+ }
-
- //----- from 68k.c start
-
--
--
--
--
--
- /* Stack checking and automatic extension support. */
-
- void
- amigaos_prologue_begin_hook (FILE *stream, int fsize)
--{
-- if (TARGET_STACKCHECK)
-- {
-- if (fsize < 256)
-+ {
-+ 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
-+ "\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);
-- }
--}
-+ fsize);
+ }
+ }
-
- void
- amigaos_alternate_frame_setup_f (FILE *stream, int fsize)
--{
-- if (fsize < 128)
++
++void
++amigaos_alternate_frame_setup_f (int fsize)
+ {
++#if 0
+ 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, "\tcmpl %s,%Rsp\n"
+ "\tjcc 0f\n"
+ "\tmoveq %I%d,%Rd0\n"
+ "\tmoveq %I0,%Rd1\n"
@@ -18502,28 +6835,17 @@ index d385ab1ff108..c93188a3e90d 100644
+ "___stk_limit")),
+ fsize, -fsize);
+ else
- asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__link_a5_d0_f\n",
-- fsize);
--}
++ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__link_a5_d0_f\n",
+ fsize);
++#endif
+ }
-
- void
- amigaos_alternate_frame_setup (FILE *stream, int fsize)
--{
-- if (!fsize)
++
++void
++amigaos_alternate_frame_setup (int fsize)
+ {
++#if 0
+ 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 %I0,%Rd0\n"
+ "\tmoveq %I0,%Rd1\n"
@@ -18533,17 +6855,7 @@ index d385ab1ff108..c93188a3e90d 100644
+ (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, "\tcmpl %s,%Rsp\n"
+ "\tjcc 0f\n"
+ "\tmoveq %I%d,%Rd0\n"
+ "\tmoveq %I0,%Rd1\n"
@@ -18554,10689 +6866,2025 @@ index d385ab1ff108..c93188a3e90d 100644
+ "___stk_limit")),
+ fsize, -fsize);
+ else
- asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__sub_d0_sp_f\n",
-- fsize);
--}
++ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__sub_d0_sp_f\n",
+ fsize);
++#endif
+ }
-
- //static rtx
- //gen_stack_management_call (rtx stack_pointer, rtx arg, const char *func)
-@@ -385,7 +380,8 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- struct amigaos_args * cum = decl == current_function_decl ? &mycum : &othercum;
- *cump = decl == current_function_decl;
- cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
-- DPRINTF(("0amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
-+ DPRINTF(
-+ ("0amigaos_init_cumulative_args %s %p -> %d\r\n", decl ? lang_hooks.decl_printable_name (decl, 2) : "?", cum, cum->num_of_regs));
-
- /* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
-@@ -394,28 +390,32 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- cum->last_arg_reg = -1;
- cum->regs_already_used = 0;
-
-- if (decl)
-+ if (fntype)
- {
-- tree attrs = DECL_ATTRIBUTES(decl);
-- if (lookup_attribute ("stkparm", attrs))
-- cum->num_of_regs = 0;
-- else
-+ tree attrs = decl ? DECL_ATTRIBUTES(decl) : NULL;
-+ if (attrs)
- {
-- tree ratree = lookup_attribute ("regparm", attrs);
-- cum->num_of_regs = amigaos_regparm != 0 ?
-- amigaos_regparm : AMIGAOS_DEFAULT_REGPARM;
-- if (ratree)
-+ if (lookup_attribute ("stkparm", attrs))
-+ cum->num_of_regs = 0;
-+ else
- {
-- tree args = TREE_VALUE(ratree);
--
-- if (args && TREE_CODE (args) == TREE_LIST)
-+ tree ratree = lookup_attribute ("regparm", attrs);
-+ cum->num_of_regs = amigaos_regparm != 0 ?
-+ amigaos_regparm :
-+ AMIGAOS_DEFAULT_REGPARM;
-+ if (ratree)
- {
-- tree val = TREE_VALUE(args);
-- if (TREE_CODE (val) == INTEGER_CST)
-+ tree args = TREE_VALUE(ratree);
+
-+ if (args && TREE_CODE (args) == TREE_LIST)
- {
-- int no = TREE_INT_CST_LOW(val);
-- if (no > 0 && no < AMIGAOS_MAX_REGPARM)
-- cum->num_of_regs = no;
-+ tree val = TREE_VALUE(args);
-+ if (TREE_CODE (val) == INTEGER_CST)
-+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no > 0 && no < AMIGAOS_MAX_REGPARM)
-+ cum->num_of_regs = no;
-+ }
- }
- }
- }
-@@ -442,7 +442,7 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
- int sz = type ? TREE_INT_CST_LOW(type) : 0;
- if (sz > 64) /* mark a0 as already used. */
-- cum->regs_already_used |= 1<<8;
-+ cum->regs_already_used |= 1 << 8;
- }
- }
-
-@@ -465,13 +465,12 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- /* Update the data in CUM to advance over an argument. */
-
- void
--amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree,
-- bool)
-+amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree, bool)
- {
- struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
- /* Update the data in CUM to advance over an argument. */
-
-- DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cump));
-+ DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cum));
-
- if (cum->last_arg_reg != -1)
- {
-@@ -507,8 +506,7 @@ _m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree typ
-
- /* 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))
-+ GET_MODE_UNIT_SIZE (mode) <= 12 && (GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT || mode == SCmode))
- {
- regbegin = 16; /* FPx */
- len = GET_MODE_NUNITS(mode);
-@@ -534,8 +532,7 @@ _m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree typ
- if (!(cum->regs_already_used & mask))
- {
- int end;
-- for (end = reg; end < cum->num_of_regs && end < reg + len;
-- end++, mask <<= 1)
-+ 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)
-@@ -546,7 +543,7 @@ _m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree typ
- }
- }
-
-- if (reg == cum->num_of_regs && altregbegin != -1)
-+ if (reg == cum->num_of_regs && altregbegin != -1)
- {
- DPRINTF(("look for alt reg\n"));
- regbegin = altregbegin;
-@@ -568,14 +565,15 @@ _m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree typ
- in a register, and which register. */
-
- struct rtx_def *
--amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
-- const_tree type, bool)
-+amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool)
- {
- DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p));
-
- struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
-
-- tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
-+ tree asmtree = type ? TYPE_ATTRIBUTES(cum->formal_type ? TREE_VALUE(cum->formal_type) : type) : NULL_TREE;
-+ //tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
++#if 0
++extern bool debug_recog(char const * txt, int which_alternative, int n, rtx * operands)
++{
++ fprintf(stderr, "%s: %d ", txt, which_alternative);
++ for (int i = 0; i < n; ++i)
++ print_rtl(stderr, operands[i]);
++ fprintf(stderr, "\n--\n");
++ return true;
++}
++#endif
+diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
+new file mode 100644
+index 000000000000..1b60ed633a3a
+--- /dev/null
++++ gcc/config/m68k/amigaos.h
+@@ -0,0 +1,504 @@
++/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
++ *
++ * This file is only included and used inside m68k.c to define the target.
++ *
++ 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.
+
- if (asmtree && 0 == strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
- {
- int i;
-@@ -596,18 +594,18 @@ amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode,
- return _m68k_function_arg (cum, mode, type);
- }
-
--void amiga_emit_regparm_clobbers(void)
-+void
-+amiga_emit_regparm_clobbers (void)
- {
-- rtx sp = gen_raw_REG(Pmode, 15);
-+ rtx sp = gen_raw_REG (Pmode, 15);
- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- if (mycum.regs_already_used & (1 << i))
- {
-- rtx reg = gen_raw_REG(Pmode, i);
-- emit_insn(gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, gen_rtx_MEM(Pmode, reg))));
-+ rtx reg = gen_raw_REG (Pmode, i);
-+ emit_insn (gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, gen_rtx_MEM(Pmode, reg))));
- }
- }
-
--
- /* 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). */
-@@ -633,8 +631,7 @@ amigaos_comp_type_attributes (const_tree type1, const_tree type2)
- attr2 = NULL_TREE;
- if (attr1 && attr2)
- {
-- if (TREE_FIXED_CST_PTR(TREE_VALUE(attr1))->data.low
-- != TREE_FIXED_CST_PTR(TREE_VALUE(attr2))->data.low)
-+ if (TREE_FIXED_CST_PTR(TREE_VALUE(attr1))->data.low != TREE_FIXED_CST_PTR(TREE_VALUE(attr2))->data.low)
- return 0;
- }
- else if (attr1 || attr2)
-@@ -647,140 +644,135 @@ amigaos_comp_type_attributes (const_tree type1, const_tree type2)
- }
-
- /* 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). */
-+ one if they are compatible, and two if they are nearly compatible
-+ (which causes a warning to be generated). */
- #if 0
- static int
- m68k_comp_type_attributes (tree type1, tree type2)
--{
-+ {
-
-- /* Functions or methods are incompatible if they specify mutually
-+ /* 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)))
-+ 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)
-+ 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)
-+ }
-+ 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)
-+ }
-+ 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;
-+ return 1;
- #endif
--}
-+ }
- #endif
-
- /* end-GG-local */
-
--
- /* Handle a "regparm", "stkparm" attribute;
- arguments as in struct attribute_spec.handler. */
- tree
--amigaos_handle_type_attribute (tree *node, tree name, tree args,
-- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-+amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
- {
- tree nnn = *node;
-- do { // while (0);
-- DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
-- if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE
-- || TREE_CODE (nnn) == 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))
-+ do
-+ { // while (0);
-+ DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
-+ if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE || TREE_CODE (nnn) == METHOD_TYPE)
- {
-- DPRINTF(("regparm found\n"));
--
-- if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
-- {
-- error ("`regparm' and `stkparm' are mutually exclusive");
-- break;
-- }
-- if (args && TREE_CODE (args) == TREE_LIST)
-+ /* 'regparm' accepts one optional argument - number of registers in
-+ single class that should be used to pass arguments. */
-+ if (is_attribute_p ("regparm", name))
- {
-- tree val = TREE_VALUE(args);
-- DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
-- if (TREE_CODE (val) == INTEGER_CST)
-+ DPRINTF(("regparm found\n"));
++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.
+
-+ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ if (args && TREE_CODE (args) == TREE_LIST)
- {
-- int no = TREE_INT_CST_LOW(val);
-- if (no < 0 || no > AMIGAOS_MAX_REGPARM)
-+ tree val = TREE_VALUE(args);
-+ DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
-+ if (TREE_CODE (val) == INTEGER_CST)
- {
-- error ("`regparm' attribute: value %d not in [0 - %d]",
-- no,
-- AMIGAOS_MAX_REGPARM);
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no < 0 || no > AMIGAOS_MAX_REGPARM)
-+ {
-+ error ("`regparm' attribute: value %d not in [0 - %d]", no,
-+ AMIGAOS_MAX_REGPARM);
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ error ("invalid argument(s) to `regparm' attribute");
- break;
- }
- }
-- else
-+ }
-+ else if (is_attribute_p ("stkparm", name))
-+ {
-+ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
- {
-- error ("invalid argument(s) to `regparm' attribute");
-+ error ("`regparm' and `stkparm' are mutually exclusive");
- break;
- }
- }
-- }
-- else if (is_attribute_p ("stkparm", name))
-- {
-- if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
-+ else if (is_attribute_p ("stackext", name))
- {
-- error ("`regparm' and `stkparm' are mutually exclusive");
-- break;
-+ if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`stackext' and `interrupt' are mutually exclusive");
-+ break;
-+ }
- }
-- }
-- else if (is_attribute_p ("stackext", name))
-- {
-- if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
-+ else if (is_attribute_p ("saveds", name))
- {
-- error ("`stackext' and `interrupt' are mutually exclusive");
-- break;
- }
- }
-- else if (is_attribute_p ("saveds", name))
-+ else
- {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to functions", IDENTIFIER_POINTER(name));
- }
-+ return NULL_TREE ;
- }
-- else
-- {
-- warning (OPT_Wattributes, "`%s' attribute only applies to functions",
-- IDENTIFIER_POINTER(name));
-- }
-- return NULL_TREE;
-- } while (0);
-+ while (0);
- // error case
- *no_add_attrs = true;
-- return NULL_TREE;
-+ return NULL_TREE ;
- }
-
--
- extern bool
- m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-
- bool
--amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
-- int *total, bool speed)
-+amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, bool speed)
- {
- // DPRINTF(("outer: %d, opno: %d", outer_code, opno));
- bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
-@@ -790,13 +782,12 @@ amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
- return r;
- }
-
--
- /* Output assembly to switch to section NAME with attribute FLAGS. */
-
- extern void
- amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
- {
-- if (0 == strncmp(".text", name, 5))
-+ if (0 == strncmp (".text", name, 5))
- name = ".text";
- fprintf (asm_out_file, "\t%s\n", name);
- }
-@@ -806,7 +797,8 @@ amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_U
- /**
- * Does x reference the pic_reg and is const or plus?
- */
--int amiga_is_const_pic_ref(const_rtx x)
-+int
-+amiga_is_const_pic_ref (const_rtx x)
- {
- const_rtx y = x;
- if (flag_pic < 3)
-@@ -816,19 +808,18 @@ int amiga_is_const_pic_ref(const_rtx x)
- return (x != y && REG_P(y) && REGNO(y) == PIC_REG);
- }
-
--
- /* 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.
-+ so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true.
-
-- This function is used in base relative code generation. */
-+ 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);
-+ operand = XEXP(XEXP (operand, 0), 0);
- if (GET_CODE (operand) == SYMBOL_REF)
-- return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
-+ return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P(operand);
- return 1;
- }
-
-
-From cbc99060c9a11080a62913d87030ad33ca15ae66 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 24 Apr 2017 23:55:30 +0200
-Subject: [PATCH 088/303] @B fix handling of jumps/labels in opt_reg_rename
-
----
- gcc/bbb-opts.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++--------
- 1 file changed, 97 insertions(+), 14 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index d0288f254f9c..db99815fee58 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -212,7 +212,6 @@ struct insn_info
- _use &= ~o._def;
- _use |= o._use;
- _def = 0;
-- _hard &= ~_use;
- }
-
- inline bool
-@@ -339,6 +338,9 @@ copy_reg (rtx reg, int newregno)
- static void
- temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldregno, unsigned newregno)
- {
-+ if (!x)
-+ return;
++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.
+
- RTX_CODE code = GET_CODE(x);
-
- const char *fmt = GET_RTX_FORMAT(code);
-@@ -542,6 +544,7 @@ update_insn_infos (void)
- if (pass && infos[pos].contains (ii))
- break;
-
-+ ii._hard = 0;
- ii |= infos[pos];
-
- if (LABEL_P(insn))
-@@ -646,7 +649,7 @@ update_insn_infos (void)
- use.scan (pattern);
- if (single_set (insn) == 0)
- use._hard = use._use | use._def;
--
-+ else
- /* if not cc0 defined check for mod. */
- if (!use.is_def (FIRST_PSEUDO_REGISTER))
- {
-@@ -684,6 +687,34 @@ bit2regno (unsigned bit)
- return regno;
- }
-
-+static unsigned
-+find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
-+{
-+ /* search the start. */
-+ while (start < 0)
-+ {
-+ unsigned startm1 = start - 1;
++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. */
+
-+ /* already searched. */
-+ if (found.find (startm1) != found.end ())
-+ break;
++#ifndef TARGET_AMIGAOS
++#define TARGET_AMIGAOS 1
++#endif
+
-+ /* do not run over RETURNS */
-+ rtx_insn * before = insns[startm1];
-+ if (JUMP_P(before) && ANY_RETURN_P(PATTERN (before)))
-+ break;
++#if 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
+
-+ start = startm1;
++/* Call __flush_cache() after building the trampoline: it will call
++ an appropriate OS cache-clearing routine. */
+
-+ /* found the definition without use. */
-+ insn_info & jj = infos[start];
-+ if (jj.is_def (rename_regno) && !jj.is_use (rename_regno))
-+ break;
++#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)
+
-+ }
-+ return start;
-+}
++#endif
+
- /*
- * Always prefer lower register numbers within the class.
- */
-@@ -696,10 +727,12 @@ opt_reg_rename (void)
- insn_info & ii = infos[index];
-
- /* do not rename if register is hard or used in same statement. */
-- const unsigned toRename = ii._def & ~ii._hard & ~ii._use;
-- if (!toRename)
-+ const unsigned rename_regbit = ii._def & ~ii._hard & ~ii._use;
-+ if (!rename_regbit)
- continue;
-
-+ const unsigned rename_regno = bit2regno (rename_regbit);
++/* 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},*/
+
- /* get the mask for free registers. */
- unsigned mask = ii.get_free_mask ();
- if (!mask)
-@@ -717,11 +750,36 @@ opt_reg_rename (void)
- unsigned pos = todo[todo.size () - 1];
- todo.pop_back ();
-
-+ /* already searched. */
- if (found.find (pos) != found.end ())
- continue;
-
-- if (LABEL_P(insns[pos]))
-+ rtx_insn * insn = insns[pos];
-+ if (LABEL_P(insn))
- {
-+ found.insert (pos);
+
-+ /* for each jump to this label:
-+ * check if the reg was used at that jump.
-+ * if used, find def
-+ */
-+ for (std::vector<rtx_insn *>::iterator i = jumps.begin (); i != jumps.end (); ++i)
-+ {
-+ if (JUMP_LABEL(*i) == insn)
-+ {
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find (*i);
-+ if (j == insn2index.end ())
-+ continue;
++/* 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
+
-+ unsigned start = j->second;
-+ if (!infos[start].is_use (rename_regno))
-+ continue;
+
-+ start = find_start (found, start, rename_regno);
-+ todo.push_back (start);
-+ }
-+ }
++/* Compile with stack extension. */
+
- if (pos + 1 < insns.size ())
- todo.push_back (pos + 1);
- continue;
-@@ -730,18 +788,18 @@ opt_reg_rename (void)
- insn_info & jj = infos[pos];
-
- /* marked as hard reg -> invalid rename */
-- if (jj._hard & toRename)
-+ if (jj._hard & rename_regbit)
- mask = 0;
-
- /* defined again -> invalid rename */
-- if ((jj._def & toRename) && !(jj._use & toRename))
-+ if ((jj._def & rename_regbit) && !(jj._use & rename_regbit))
- mask = 0;
-
- if (!mask)
- break;
-
- /* not used. */
-- if (!(jj._use & toRename))
-+ if (!(jj._use & rename_regbit))
- continue;
-
- /* update free regs. */
-@@ -753,17 +811,41 @@ opt_reg_rename (void)
- found.insert (pos);
-
- /* follow jump and/or next insn. */
-- rtx_insn * insn = insns[pos];
- if (JUMP_P(insn))
- {
- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-- if (j != insn2index.end ())
-- todo.push_back (j->second);
-+ if (j == insn2index.end ())
-+ {
-+ /* whoops - label not found. */
-+ todo.clear ();
-+ mask = 0;
-+ break;
-+ }
-
-+ unsigned label_index = j->second;
-+ if (found.find (label_index) == found.end ())
-+ {
-+ /* if the rename_reg is used in the insn before.
-+ * search the start.
-+ */
-+ if (label_index > 0)
-+ {
-+ insn_info & bb = infos[label_index - 1];
-+ if (bb.is_use (rename_regbit))
-+ {
-+ unsigned start = find_start (found, label_index - 1, rename_regno);
-+ todo.push_back (start);
-+ }
-+ }
-+ todo.push_back (label_index);
-+ }
- rtx jmppattern = PATTERN (insn);
- if (GET_CODE(jmppattern) == PARALLEL)
- {
-- return 0; /* can't handle yet. Abort renaming. */
-+ /* can't handle yet. Abort renaming. */
-+ todo.clear ();
-+ mask = 0;
-+ break;
- }
-
- rtx jmpsrc = XEXP(jmppattern, 1);
-@@ -777,7 +859,7 @@ opt_reg_rename (void)
-
- if (mask)
- {
-- int oldregno = bit2regno (toRename);
-+ int oldregno = bit2regno (rename_regbit);
- int newregno = bit2regno (mask);
-
- /* check the renamed insns. */
-@@ -812,7 +894,8 @@ opt_reg_rename (void)
- if (!ok)
- continue;
-
-- log ("opt_reg_rename %s -> %s (%d locs)\n", reg_names[oldregno], reg_names[newregno], patch.size ());
-+ log ("opt_reg_rename %s -> %s (%d locs, start at %d)\n", reg_names[oldregno], reg_names[newregno],
-+ patch.size (), index);
-
- /* apply all changes. */
- for (std::vector<std::pair<rtx *, rtx> >::iterator j = patch.begin (); j != patch.end (); ++j)
-
-From ee7031d5d1442ca1e933b3cb029f91ba1534354d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 25 Apr 2017 11:30:06 +0200
-Subject: [PATCH 089/303] @B fix regrename...
-
----
- gcc/bbb-opts.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index db99815fee58..3e6c316149b0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -691,7 +691,7 @@ static unsigned
- find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
- {
- /* search the start. */
-- while (start < 0)
-+ while (start > 0)
- {
- unsigned startm1 = start - 1;
-
-
-From e550db50f02dfa9bcfdf533e664ab032fca2a235 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 25 Apr 2017 12:42:11 +0200
-Subject: [PATCH 090/303] @R add target 'amigaosvasm' from
- https://github.com/alpine9000/gcc
-
----
- config.sub | 6 ++--
- gcc/config.gcc | 10 ++++++
- gcc/config/m68k/amigaos.c | 19 ++++++++++-
- gcc/config/m68k/m68k.c | 17 +++++++++-
- gcc/config/m68k/m68k.h | 78 +++++++++++++++++++++++++++++++++++++++++--
- gcc/config/m68k/m68kamigaos.h | 66 ++++++++++++++++++++++++++++++++++--
- 6 files changed, 185 insertions(+), 11 deletions(-)
-
-diff --git a/config.sub b/config.sub
-index 41146e11c6c9..35247fe0c474 100755
---- config.sub
-+++ config.sub
-@@ -2,7 +2,7 @@
- # Configuration validation subroutine script.
- # Copyright 1992-2016 Free Software Foundation, Inc.
-
--timestamp='2016-01-01'
-+timestamp='2017-04-21'
-
- # This file is free software; you can redistribute it and/or modify it
- # under the terms of the GNU General Public License as published by
-@@ -500,7 +500,7 @@ case $basic_machine in
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
-- amigaos | amigados)
-+ amigaos | amigaosvasm | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
-@@ -1380,7 +1380,7 @@ case $os in
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* | -cloudabi* | -sortix* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-+ | -clix* | -riscos* | -uniplus* | -iris* | -rt* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-diff --git a/gcc/config.gcc b/gcc/config.gcc
-index 762594c073ae..0beee32c863c 100644
---- gcc/config.gcc
-+++ gcc/config.gcc
-@@ -1936,6 +1936,16 @@ m68k-*-elf* | fido-*-elf*)
- ;;
- esac
- ;;
-+m68k*-*-amigaosvasm*)
-+ default_m68k_cpu=68000
-+ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
-+ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_AMIGAOS_VASM TARGET_CPU_DEFAULT=0"
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
-+ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
-+ extra_objs=amigaos.o
-+ extra_options="${extra_options} m68k/amigaos.opt"
-+ gnu_ld=yes
-+ ;;
- m68k*-*-amigaos*)
- default_m68k_cpu=68000
- tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index c93188a3e90d..27831df2d543 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -50,6 +50,7 @@
-
- //int amiga_declare_object;
-
++#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))))
+
- #if 0
- static int amigaos_put_in_text (tree);
- static rtx gen_stack_management_call (rtx, rtx, const char *);
-@@ -783,7 +784,7 @@ amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *tota
- }
-
- /* Output assembly to switch to section NAME with attribute FLAGS. */
--
-+#ifndef TARGET_AMIGAOS_VASM
- extern void
- amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
- {
-@@ -791,6 +792,22 @@ amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_U
- name = ".text";
- fprintf (asm_out_file, "\t%s\n", name);
- }
-+#else
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
-+{
-+ if (0 == strncmp(".text", name, 5))
-+ name = ".text";
++///* 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))))
+
-+ if (0 == strncmp("section ", name, 8)) {
-+// fprintf (asm_out_file, "\t.section\t%s\n", name);
-+ fprintf (asm_out_file, "\t%s\n", name);
-+ } else {
-+ fprintf (asm_out_file, "\tsection %s\n", name);
-+ }
-+}
-+#endif
++/* Compile with a4 restoring in public functions. */
+
-
- /* Baserel support. */
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 3fabe00a678a..8a40cbc2ab1f 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -191,7 +191,11 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
-
- #if INT_OP_GROUP == INT_OP_DOT_WORD
- #undef TARGET_ASM_ALIGNED_HI_OP
-+#ifndef TARGET_AMIGAOS_VASM
- #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
-+#else
-+#define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
-+#endif
- #endif
-
- #if INT_OP_GROUP == INT_OP_NO_DOT
-@@ -595,8 +599,11 @@ m68k_option_override (void)
- if (!flag_pic || flag_pic > 2)
- {
- m68k_symbolic_call_var = M68K_SYMBOLIC_CALL_JSR;
--
-+#ifndef TARGET_AMIGAOS_VASM
- m68k_symbolic_jump = "jra %a0";
-+#else
-+ m68k_symbolic_jump = "jmp %a0";
-+#endif
- }
- else if (TARGET_ID_SHARED_LIBRARY)
- /* All addresses must be loaded from the GOT. */
-@@ -1831,13 +1838,21 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx_insn *insn, int signpos
- && next_insn_tests_no_inequality (insn))
- {
- cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N | CC_NO_OVERFLOW;
-+#ifndef TARGET_AMIGAOS_VASM
- return "move%.w %1,%%ccr";
-+#else
-+ return "move%.w %1,ccr";
-+#endif
- }
- if (count == 2 && DATA_REG_P (operands[1])
- && next_insn_tests_no_inequality (insn))
- {
- cc_status.flags = CC_NOT_NEGATIVE | CC_INVERTED | CC_NO_OVERFLOW;
-+#ifndef TARGET_AMIGAOS_VASM
- return "move%.w %1,%%ccr";
-+#else
-+ return "move%.w %1,ccr";
-+#endif
- }
- /* count == 1 followed by bvc/bvs and
- count == 0 followed by bcc/bcs are also possible, but need
-diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
-index 5142adf24e4d..200f07ef63a4 100644
---- gcc/config/m68k/m68k.h
-+++ gcc/config/m68k/m68k.h
-@@ -204,7 +204,11 @@ along with GCC; see the file COPYING3. If not see
- #define INT_OP_DC 3 /* dc.b, dc.w, dc.l */
-
- /* Set the default. */
-+#ifndef TARGET_AMIGAOS_VASM
- #define INT_OP_GROUP INT_OP_DOT_WORD
-+#else
-+#define INT_OP_GROUP INT_OP_DC
-+#endif
-
- /* Bit values used by m68k-devices.def to identify processor capabilities. */
- #define FL_BITFIELD (1 << 0) /* Support bitfield instructions. */
-@@ -729,9 +733,49 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
- if (cc_prev_status.flags & CC_NO_OVERFLOW) \
- return NO_OV; \
- return NORMAL; } while (0)
++#define MASK_RESTORE_A4 0x10000000 /* 1 << 28 */
++#define TARGET_RESTORE_A4 \
++ ((target_flags & MASK_RESTORE_A4) && TREE_PUBLIC (current_function_decl))
+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
-+ do { \
-+ FILE *_hide_asm_out_file = (MYFILE); \
-+ const unsigned char *_hide_p = (const unsigned char *) (MYSTRING); \
-+ int _hide_thissize = (MYLENGTH); \
-+ { \
-+ FILE *asm_out_file = _hide_asm_out_file; \
-+ const unsigned char *p = _hide_p; \
-+ int thissize = _hide_thissize; \
-+ int i; \
-+ fprintf (asm_out_file, "\tdc.b \""); \
-+ \
-+ for (i = 0; i < thissize; i++) \
-+ { \
-+ int c = p[i]; \
-+ if (c == '\"' || c == '\\') \
-+ putc ('\\', asm_out_file); \
-+ if (ISPRINT (c)) \
-+ putc (c, asm_out_file); \
-+ else \
-+ { \
-+ fprintf (asm_out_file, "\\%o", c); \
-+ /* After an octal-escape, if a digit follows, \
-+ terminate one string constant and start another. \
-+ The VAX assembler fails to stop reading the escape \
-+ after three digits, so this is the only way we \
-+ can get it to parse the data properly. */ \
-+ if (i < thissize - 1 && ISDIGIT (p[i + 1])) \
-+ fprintf (asm_out_file, "\"\n\tdc.b \""); \
-+ } \
-+ } \
-+ fprintf (asm_out_file, "\"\n"); \
-+ } \
-+ } \
-+ while (0)
-+#endif
-
++/* Compile with a4 restoring in all functions. */
+
- /* Control the assembler format that we output. */
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_APP_ON "#APP\n"
- #define ASM_APP_OFF "#NO_APP\n"
- #define TEXT_SECTION_ASM_OP "\t.text"
-@@ -741,6 +785,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
- #define LOCAL_LABEL_PREFIX ""
- #define USER_LABEL_PREFIX "_"
- #define IMMEDIATE_PREFIX "#"
-+#else
-+#define ASM_APP_ON ""
-+#define ASM_APP_OFF ""
-+#define TEXT_SECTION_ASM_OP "\tsection .text"
-+#define DATA_SECTION_ASM_OP "\tsection .data"
-+#define GLOBAL_ASM_OP "\txdef\t"
-+#define REGISTER_PREFIX ""
-+#define LOCAL_LABEL_PREFIX "_."
-+#define USER_LABEL_PREFIX "_"
-+#define IMMEDIATE_PREFIX "#"
-+#endif
-
- #define REGISTER_NAMES \
- {REGISTER_PREFIX"d0", REGISTER_PREFIX"d1", REGISTER_PREFIX"d2", \
-@@ -860,11 +915,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-
- /* The m68k does not use absolute case-vectors, but we must define this macro
- anyway. */
--#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- asm_fprintf (FILE, "\t.long %LL%d\n", VALUE)
--
--#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL)
-+#else
-+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-+ asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
-+#endif
-
- /* We don't have a way to align to more than a two-byte boundary, so do the
- best we can and don't complain. */
-@@ -874,13 +935,24 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-
- #ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
- /* Use "move.l %a4,%a4" to advance within code. */
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
- if ((LOG) > 0) \
- fprintf ((FILE), "\t.balignw %u,0x284c\n", 1 << (LOG));
- #endif
-+#else
-+#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "\tcnop 0,%u\n", 1 << (LOG));
-+#endif
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
-+#else
-+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
-+ fprintf (FILE, "\tds.b %u\n", (int)(SIZE))
-+#endif
-
- #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
- ( fputs (".comm ", (FILE)), \
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 20e0b66face2..3ca2cd666e7c 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -61,7 +61,11 @@ along with GCC; see the file COPYING3. If not see
- These labels will not appear in the symbol table. */
-
- #undef LOCAL_LABEL_PREFIX
-+#ifndef TARGET_AMIGAOS_VASM
- #define LOCAL_LABEL_PREFIX "."
-+#else
-+#define LOCAL_LABEL_PREFIX "_."
-+#endif
-
- /* The prefix to add to user-visible assembler symbols. */
-
-@@ -71,24 +75,43 @@ along with GCC; see the file COPYING3. If not see
- /* config/m68k.md has an explicit reference to the program counter,
- prefix this by the register prefix. */
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_RETURN_CASE_JUMP \
- do { \
- return "jmp %%pc@(2,%0:w)"; \
- } while (0)
-+#else
-+#define ASM_RETURN_CASE_JUMP \
-+ do { \
-+ return "jmp (2,pc,%0.w)"; \
-+ } while (0)
-+#endif
-
- /* This is how to output an assembler line that says to advance the
- location counter to a multiple of 2**LOG bytes. */
-
-+#ifndef TARGET_AMIGAOS_VASM
- #ifndef ALIGN_ASM_OP
- #define ALIGN_ASM_OP "\t.align\t"
- #endif
-+#else
-+#define ALIGN_ASM_OP "\talign\t"
-+#endif
-
- #undef ASM_OUTPUT_ALIGN
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_ALIGN(FILE,LOG) \
- do { \
- if ((LOG) > 0) \
- fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, 1 << (LOG)); \
- } while (0)
-+#else
-+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-+do { \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, (LOG)); \
-+} while (0)
-+#endif
-
- #if 0
- extern int amiga_declare_object;
-@@ -126,7 +149,11 @@ amiga_declare_object = 0
- #undef M68K_STATIC_CHAIN_REG_NAME
- #define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a1"
-
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_COMMENT_START "|"
-+#else
- #define ASM_COMMENT_START "|"
-+#endif
-
- /* Define how the m68k registers should be numbered for Dwarf output.
- The numbering provided here should be compatible with the native
-@@ -147,15 +174,34 @@ amiga_declare_object = 0
-
- #undef ASM_OUTPUT_COMMON
- #undef ASM_OUTPUT_LOCAL
--#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
- ( fputs (".comm ", (FILE)), \
- assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (int)(SIZE)))
-+#else
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ ( switch_to_section (bss_section), \
-+ fputs ("|.comm\n\tcnop 0,4\n", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)), \
-+ fputs ("\txdef ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), "\n"))
-+#endif
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
- ( fputs (".lcomm ", (FILE)), \
- assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (int)(SIZE)))
-+#else
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+( switch_to_section (bss_section), \
-+ fputs ("|.lcomm\n\tcnop 0,4\n", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)))
-+#endif
-
- /* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
- keep switch tables in the text section. */
-@@ -169,9 +215,13 @@ amiga_declare_object = 0
- fprintf ((FILE), "%s&%d\n", SWBEG_ASM_OP, XVECLEN (PATTERN (TABLE), 1));
- /* end of stuff from m68kv4.h */
-
-+#ifndef TARGET_AMIGAOS_VASM
- #ifndef BSS_SECTION_ASM_OP
- #define BSS_SECTION_ASM_OP "\t.bss"
- #endif
-+#else
-+#define BSS_SECTION_ASM_OP "\tsection\tbss"
-+#endif
-
- #ifndef ASM_OUTPUT_ALIGNED_BSS
- #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-@@ -294,8 +344,13 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- /* Various -m flags require special flags to the assembler. */
-
- #undef ASM_SPEC
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_SPEC \
-+ "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
-+#else
- #define ASM_SPEC \
-- "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
-+ "-gas -esc -ldots -Fhunk -quiet %(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
-+#endif
-
- #undef ASM_CPU_SPEC
- #define ASM_CPU_SPEC \
-@@ -305,8 +360,13 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{m68040} " \
- "%{m68060}"
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_CPU_DEFAULT_SPEC \
-- "%{!m680*:%{!mc680*:-m68040}}"
-+ "%{!m680*:%{!mc680*:-m68040}}"
-+#else
-+#define ASM_CPU_DEFAULT_SPEC \
-+ "%{!m680*:%{!mc680*:-m68000}}"
-+#endif
-
- /* Choose the right startup file, depending on whether we use base relative
- code, base relative code with automatic relocation (-resident), their
-
-From c48a0f72eefe8e3a45b24184fc75e5a93eaabfc2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 25 Apr 2017 19:37:45 +0200
-Subject: [PATCH 091/303] @B renaming is better again, test cases stil ok
-
----
- gcc/bbb-opts.c | 163 +++++++++++++++++++++++++++++----------------------------
- 1 file changed, 82 insertions(+), 81 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 3e6c316149b0..407e2f74fd9f 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -738,123 +738,124 @@ opt_reg_rename (void)
- if (!mask)
- continue;
-
-- std::set<unsigned> found;
-+ /* first = pos to start, second indicates to treat def as use. */
- std::vector<unsigned> todo;
-+ std::set<unsigned> found;
- if (index + 1 < insns.size ())
- todo.push_back (index + 1);
-
-+// /* trigger jump checking */
-+// if (index > 0 && LABEL_P(insns[index - 1]))
-+// todo.push_back (std::make_pair(index - 1, 0));
-+
- found.insert (index);
- /* a register was defined, follow all branches. */
-- while (todo.size ())
-+ while (mask && todo.size ())
- {
-- unsigned pos = todo[todo.size () - 1];
-+ unsigned runpos = todo[todo.size () - 1];
- todo.pop_back ();
-
-- /* already searched. */
-- if (found.find (pos) != found.end ())
-- continue;
--
-- rtx_insn * insn = insns[pos];
-- if (LABEL_P(insn))
-+ for (unsigned pos = runpos; mask && pos < insns.size (); ++pos)
- {
-- found.insert (pos);
-+ /* already searched. */
-+ if (found.find (pos) != found.end ())
-+ break;
-
-- /* for each jump to this label:
-- * check if the reg was used at that jump.
-- * if used, find def
-- */
-- for (std::vector<rtx_insn *>::iterator i = jumps.begin (); i != jumps.end (); ++i)
-+ rtx_insn * insn = insns[pos];
-+ if (LABEL_P(insn))
- {
-- if (JUMP_LABEL(*i) == insn)
-+ found.insert (pos);
++#define MASK_ALWAYS_RESTORE_A4 0x8000000 /* 1 << 27 */
++#define TARGET_ALWAYS_RESTORE_A4 (target_flags & MASK_ALWAYS_RESTORE_A4)
+
-+ /* for each jump to this label:
-+ * check if the reg was used at that jump.
-+ * if used, find def
-+ */
-+ for (std::vector<rtx_insn *>::iterator i = jumps.begin (); i != jumps.end (); ++i)
- {
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find (*i);
-- if (j == insn2index.end ())
-- continue;
-+ if (JUMP_LABEL(*i) == insn)
-+ {
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find (*i);
-+ if (j == insn2index.end ())
-+ continue;
-
-- unsigned start = j->second;
-- if (!infos[start].is_use (rename_regno))
-- continue;
-+ unsigned start = j->second;
-+ if (!infos[start].is_use (rename_regno))
-+ continue;
-
-- start = find_start (found, start, rename_regno);
-- todo.push_back (start);
-+ start = find_start (found, start, rename_regno);
-+ todo.push_back (start);
-+ }
- }
-+ continue;
- }
-
-- if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
-- continue;
-- }
-+ insn_info & jj = infos[pos];
-
-- insn_info & jj = infos[pos];
-+ /* marked as hard reg -> invalid rename */
-+ if (jj._use & jj._hard & rename_regbit)
-+ mask = 0;
-
-- /* marked as hard reg -> invalid rename */
-- if (jj._hard & rename_regbit)
-- mask = 0;
-+// /* defined again -> invalid rename */
-+// if ((jj._def & rename_regbit) && !(jj._use & rename_regbit))
-+// mask = 0;
-
-- /* defined again -> invalid rename */
-- if ((jj._def & rename_regbit) && !(jj._use & rename_regbit))
-- mask = 0;
--
-- if (!mask)
-- break;
-+ if (!mask)
-+ break;
-
-- /* not used. */
-- if (!(jj._use & rename_regbit))
-- continue;
-+ /* not used. and not a def */
-+ if (pos == runpos && (jj._def & rename_regbit))
-+ {
-+ /* continue since this pos was added by start search. */
-+ }
-+ else if (!(jj._use & rename_regbit))
-+ break;
-
-- /* update free regs. */
-- mask &= ~jj._use;
-- mask &= ~jj._def;
-- if (!mask)
-- break;
-+ /* update free regs. */
-+ mask &= ~jj._use;
-+ mask &= ~jj._def;
-+ if (!mask)
-+ break;
-
-- found.insert (pos);
-+ found.insert (pos);
-
-- /* follow jump and/or next insn. */
-- if (JUMP_P(insn))
-- {
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-- if (j == insn2index.end ())
-+ /* follow jump and/or next insn. */
-+ if (JUMP_P(insn))
- {
-- /* whoops - label not found. */
-- todo.clear ();
-- mask = 0;
-- break;
-- }
-+ std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-+ if (j == insn2index.end ())
-+ {
-+ /* whoops - label not found. */
-+ mask = 0;
-+ break;
-+ }
-
-- unsigned label_index = j->second;
-- if (found.find (label_index) == found.end ())
-- {
-- /* if the rename_reg is used in the insn before.
-- * search the start.
-- */
-- if (label_index > 0)
-+ unsigned label_index = j->second;
-+ if (found.find (label_index) == found.end ())
- {
-- insn_info & bb = infos[label_index - 1];
-+ /* if the rename_reg is used in the insn before.
-+ * search the start.
-+ */
-+ insn_info & bb = infos[label_index + 1];
- if (bb.is_use (rename_regbit))
- {
- unsigned start = find_start (found, label_index - 1, rename_regno);
- todo.push_back (start);
- }
-+ todo.push_back (label_index + 1);
-+ }
-+ rtx jmppattern = PATTERN (insn);
-+ if (GET_CODE(jmppattern) == PARALLEL)
-+ {
-+ /* can't handle yet. Abort renaming. */
-+ mask = 0;
-+ break;
- }
-- todo.push_back (label_index);
-- }
-- rtx jmppattern = PATTERN (insn);
-- if (GET_CODE(jmppattern) == PARALLEL)
-- {
-- /* can't handle yet. Abort renaming. */
-- todo.clear ();
-- mask = 0;
-- break;
-- }
-
-- rtx jmpsrc = XEXP(jmppattern, 1);
-- if (jmpsrc && GET_CODE(jmpsrc) == IF_THEN_ELSE)
-- if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (!jmpsrc || GET_CODE(jmpsrc) != IF_THEN_ELSE)
-+ break;
-+ }
- }
-- else if (pos + 1 < insns.size ())
-- todo.push_back (pos + 1);
- }
-
- if (mask)
-
-From 50dc4c0949e49397d6c6de28207d34cbf137621c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 26 Apr 2017 10:34:16 +0200
-Subject: [PATCH 092/303] @B fix backward search at labels
-
----
- gcc/bbb-opts.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 407e2f74fd9f..78eb0cc32f38 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -836,7 +836,7 @@ opt_reg_rename (void)
- * search the start.
- */
- insn_info & bb = infos[label_index + 1];
-- if (bb.is_use (rename_regbit))
-+ if (bb.is_use (rename_regno))
- {
- unsigned start = find_start (found, label_index - 1, rename_regno);
- todo.push_back (start);
-
-From ec53abb40b3066d74243c566ea7528ac1bd0f150 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 26 Apr 2017 11:43:37 +0200
-Subject: [PATCH 093/303] @I no longer using df functions to determine reg use.
- @B fixed propagate moves, @B fixed eliminate dead assignments
-
----
- gcc/bbb-opts.c | 278 +++++++++++++++++++++++++++++++--------------------------
- 1 file changed, 149 insertions(+), 129 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 78eb0cc32f38..9d138063fb27 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -58,7 +58,6 @@
- #include "backend.h"
- #include "target.h"
- #include "rtl.h"
--#include "df.h"
- #include "tm_p.h"
- #include "insn-config.h"
- #include "recog.h"
-@@ -242,6 +241,9 @@ struct insn_info
- return true;
- }
-
-+ void
-+ scan_call (rtx_insn *);
++/* Provide a dummy entry for the '-msmall-code' switch. This is used by
++ the assembler and '*_SPEC'. */
+
- void
- scan (rtx);
-
-@@ -267,6 +269,31 @@ struct insn_info
- }
- };
-
-+void
-+insn_info::scan_call (rtx_insn * insn)
-+{
-+ /* add mregparm registers. */
-+ for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
-+ {
-+ rtx op, reg;
++#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") }
+
-+ if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-+ for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
-+ use (r);
-+ }
-+ /* also mark all registers as not renamable */
-+ _hard = _use;
+
-+ scan (PATTERN (insn));
++/* Support sections in chip, fast memory, currently '.datachip', '.datafast'
++ * and '.datafar' to abs addressing with baserel. */
++extern void
++amiga_named_section (const char *name, unsigned int flags, tree decl);
+
-+ /* mark scratch registers. */
-+ def (0);
-+ def (1);
-+ def (8);
-+ def (9);
++#undef TARGET_ASM_NAMED_SECTION
++#define TARGET_ASM_NAMED_SECTION amiga_named_section
+
-+}
++/* Various ABI issues. */
+
- /* scan rtx for registers and set the corresponding flags. */
- void
- insn_info::scan (rtx x)
-@@ -478,8 +505,6 @@ update_insns ()
- rtx_insn *insn, *next;
- clear ();
-
-- // df_insn_rescan_all ();
--
- char inproepilogue = 1;
- /* create a vector with relevant insn. */
- for (insn = get_insns (); insn; insn = next)
-@@ -567,26 +592,7 @@ update_insn_infos (void)
- if (CALL_P(insn))
- {
- insn_info use;
--
-- /* add mregparm registers. */
-- for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
-- {
-- rtx op, reg;
--
-- if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-- for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
-- use.use (r);
-- }
-- /* also mark all registers as not renamable */
-- use._hard = use._use;
--
-- use.scan (pattern);
--
-- /* mark scratch registers. */
-- use.def (0);
-- use.def (1);
-- use.def (8);
-- use.def (9);
-+ use.scan_call (insn);
-
- infos[pos] = use | ii;
- ii.updateWith (use);
-@@ -687,6 +693,27 @@ bit2regno (unsigned bit)
- return regno;
- }
-
-+/* check if that register is touched between from and to, excluding from and to .*/
-+static bool
-+is_reg_touched_between (unsigned regno, int from, int to)
-+{
-+ for (int index = from + 1; index < to; ++index)
-+ {
-+ insn_info ii;
-+ rtx_insn * insn = insns[index];
-+ if (CALL_P(insn))
-+ ii.scan_call (insn);
-+ else
-+ ii.scan (PATTERN (insn));
-+ if (ii.is_use (regno) || ii.is_def (regno))
-+ return true;
-+ }
-+ return false;
-+}
++/* This is (almost;-) BSD, so it wants DBX format. */
++#undef DBX_DEBUGGING_INFO
++#define DBX_DEBUGGING_INFO
+
-+/*
-+ * search backward and find the initial assignment for that regno.
-+ */
- static unsigned
- find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
- {
-@@ -1045,47 +1072,76 @@ opt_propagate_moves ()
- if (rtx_equal_p (srci, dstj) && rtx_equal_p (srcj, dsti))
- {
- /* Ensure correct usage. */
-- if (!reg_used_between_p (srci, current_label, ii) && !reg_used_between_p (srci, ii, jj)
-- && !reg_used_between_p (srci, jj, insn) && !reg_used_between_p (dsti, current_label, ii)
-- && !reg_used_between_p (dsti, jj, insn))
-+ if (is_reg_touched_between (REGNO(srci), current_label_index, *i) // label ... move src,x
-+ || is_reg_touched_between (REGNO(srci), *i, *j) // move src,x ... move x,src
-+ || is_reg_touched_between (REGNO(srci), *j, index) // move x,src ... jcc
-+ || is_reg_touched_between (REGNO(dsti), *j, index) // label ... move src,x
-+ || is_reg_touched_between (REGNO(dsti), *j, index) // move x,src ... jcc
-+ )
-+ {
-+ ++j;
-+ continue;
-+ }
++/* GDB goes mad if it sees the function end marker. */
+
-+ std::vector<int> fixups;
++#define NO_DBX_FUNCTION_END 1
+
-+ /* if there are jumps out of the loop,
-+ * check if the modification occurs before the jump,
-+ * and if, that it's a plus const.
-+ */
-+ if (jump_out.size ())
- {
-- std::vector<int> fixups;
-+ std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
-+ int fixup = 0;
-
-- /* if there are jumps out of the loop,
-- * check if the modification occurs before the jump,
-- * and if, that it's a plus const.
-- */
-- if (jump_out.size ())
-+ for (unsigned k = *i + 1; k != *j; ++k)
- {
-- std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
-- int fixup = 0;
-+ rtx_insn * check = insns[k];
-+ if (JUMP_P(check))
-+ {
-+ fixups.push_back (fixup);
-+ if (++label_iter == jump_out.end ())
-+ break;
-+ continue;
-+ }
-
-- for (unsigned k = *i + 1; k != *j; ++k)
-+ if (reg_overlap_mentioned_p (dsti, PATTERN (check)))
- {
-- rtx_insn * check = insns[k];
-- if (JUMP_P(check))
-+ /* right now only support auto_incs. */
-+ rtx set = single_set (check);
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
++/* Allow folding division by zero. */
+
-+ if (reg_overlap_mentioned_p (dsti, dst))
- {
-- fixups.push_back (fixup);
-- if (++label_iter == jump_out.end ())
-+ if (REG_P(dst))
-+ break;
-+ if (!MEM_P(dst))
-+ break;
++#define REAL_INFINITY
+
-+ rtx x = XEXP(dst, 0);
-+ if (GET_CODE(x) == REG)
-+ fixup += 0; // direct use
-+ else if (GET_CODE(x) == PRE_INC ||
-+ GET_CODE(x) == POST_INC)
-+ fixup -= GET_MODE_SIZE(GET_MODE(dst));
-+ else if (GET_CODE(dst) == PRE_DEC ||
-+ GET_CODE(dst) == POST_DEC)
-+ fixup += GET_MODE_SIZE(GET_MODE(dst));
-+ else
- break;
-- continue;
- }
-
-- if (reg_overlap_mentioned_p (dsti, PATTERN (check)))
-+ if (reg_overlap_mentioned_p (dsti, src))
- {
-- /* right now only support auto_incs. */
-- rtx set = single_set (check);
-- rtx src = SET_SRC(set);
-- rtx dst = SET_DEST(set);
--
-- if (reg_overlap_mentioned_p (dsti, dst))
-+ if (REG_P(src))
-+ fixup += 0;
-+ else
- {
-- if (REG_P(dst))
-- break;
-- if (!MEM_P(dst))
-+ if (!MEM_P(src))
- break;
-
-- rtx x = XEXP(dst, 0);
-+ rtx x = XEXP(src, 0);
- if (GET_CODE(x) == REG)
- fixup += 0; // direct use
- else if (GET_CODE(x) == PRE_INC ||
-@@ -1097,91 +1153,64 @@ opt_propagate_moves ()
- else
- break;
- }
--
-- if (reg_overlap_mentioned_p (dsti, src))
-- {
-- if (REG_P(src))
-- fixup += 0;
-- else
-- {
-- if (!MEM_P(src))
-- break;
--
-- rtx x = XEXP(src, 0);
-- if (GET_CODE(x) == REG)
-- fixup += 0; // direct use
-- else if (GET_CODE(x) == PRE_INC ||
-- GET_CODE(x) == POST_INC)
-- fixup -= GET_MODE_SIZE(GET_MODE(dst));
-- else if (GET_CODE(dst) == PRE_DEC ||
-- GET_CODE(dst) == POST_DEC)
-- fixup += GET_MODE_SIZE(GET_MODE(dst));
-- else
-- break;
-- }
-- }
- }
- }
- }
-+ }
-
-- /* got a fixup for all jump_outs? */
-- if (fixups.size () == jump_out.size ())
-- {
-- rtx_insn * before = insns[current_label_index - 1];
-- rtx_insn * after = insns[index + 1];
-- rtx bset = single_set (before);
-+ /* got a fixup for all jump_outs? */
-+ if (fixups.size () == jump_out.size ())
-+ {
-+ rtx_insn * before = insns[current_label_index - 1];
-+ rtx_insn * after = insns[index + 1];
-+ rtx bset = single_set (before);
-
-- log ("propagate_moves condition met, moving regs %s, %s\n",
-- reg_names[REGNO(srci)],
-- reg_names[REGNO(dsti)]);
-+ log ("propagate_moves condition met, moving regs %s, %s\n",
-+ reg_names[REGNO(srci)],
-+ reg_names[REGNO(dsti)]);
-
-- /* Move in front of loop and mark as dead. */
-- rtx_insn * newii = make_insn_raw (PATTERN (ii));
-- SET_INSN_DELETED(ii);
-+ /* Move in front of loop and mark as dead. */
-+ rtx_insn * newii = make_insn_raw (PATTERN (ii));
-+ SET_INSN_DELETED(ii);
-
-- /* Plus check if the reg was just loaded. */
-- if (bset)
-+ /* Plus check if the reg was just loaded. */
-+ if (bset)
-+ {
-+ rtx bdst = SET_DEST(bset);
-+ if (REG_P(bdst) && REGNO(bdst) == REGNO(srci))
- {
-- rtx bdst = SET_DEST(bset);
-- if (REG_P(bdst) && REGNO(bdst) == REGNO(srci))
-- {
-- SET_SRC(PATTERN(newii)) = SET_SRC(bset);
-+ SET_SRC(PATTERN(newii)) = SET_SRC(bset);
- // SET_INSN_DELETED(ii);
-- }
- }
-- else
-- add_reg_note (newii, REG_DEAD, srci);
-+ }
-+ else
-+ add_reg_note (newii, REG_DEAD, srci);
-
-- add_insn_after (newii, before, 0);
-+ add_insn_after (newii, before, 0);
-
-- /* Move behind loop - into next BB. */
-- rtx_insn * newjj = make_insn_raw (PATTERN (jj));
-- add_insn_before (newjj, after, 0);
-- SET_INSN_DELETED(jj);
-+ /* Move behind loop - into next BB. */
-+ rtx_insn * newjj = make_insn_raw (PATTERN (jj));
-+ add_insn_before (newjj, after, 0);
-+ SET_INSN_DELETED(jj);
-
-- reg_reg.erase (j);
-- reg_reg.erase (i);
-- j = reg_reg.end ();
-- inc = false;
-+ reg_reg.erase (j);
-+ reg_reg.erase (i);
-+ j = reg_reg.end ();
-+ inc = false;
-
-- // df_insn_rescan (newii);
-- // df_insn_rescan (newjj);
-+ /* add fixes if there were jumps out of the loop. */
-+ if (jump_out.size ())
-+ {
-+ log ("propagate_moves fixing %d jump outs\n", jump_out.size ());
-
-- /* add fixes if there were jumps out of the loop. */
-- if (jump_out.size ())
-+ for (unsigned k = 0; k < jump_out.size (); ++k)
- {
-- log ("propagate_moves fixing %d jump outs\n", jump_out.size ());
--
-- for (unsigned k = 0; k < jump_out.size (); ++k)
-- {
-- rtx neu = gen_rtx_SET(
-- dstj, gen_rtx_PLUS(Pmode, dsti, gen_rtx_CONST_INT(Pmode, fixups[k])));
-- rtx_insn * neui = emit_insn_after (neu, jump_out[k]);
-- // df_insn_rescan (neui);
-- }
-+ rtx neu = gen_rtx_SET(
-+ dstj, gen_rtx_PLUS(Pmode, dsti, gen_rtx_CONST_INT(Pmode, fixups[k])));
-+ rtx_insn * neui = emit_insn_after (neu, jump_out[k]);
- }
-- ++change_count;
- }
-+ ++change_count;
- }
- }
- if (inc)
-@@ -1277,8 +1306,6 @@ opt_strcpy ()
- SET_INSN_DELETED(x2reg);
- SET_INSN_DELETED(insn);
-
-- // df_insn_rescan (reg2x);
--
- ++change_count;
- }
- }
-@@ -1394,9 +1421,6 @@ opt_commute_add_move (void)
-
- add_reg_note (next, REG_INC, reg1dst);
-
-- // df_insn_rescan (insn);
-- // df_insn_rescan (next);
--
- ++change_count;
- }
- }
-@@ -1579,14 +1603,14 @@ opt_const_cmp_to_sub (void)
- }
-
- /*
-- * Some optimizations (e.g. propagate_moves) might result into an unuses assignment behind the loop.
-+ * Some optimizations (e.g. propagate_moves) might result into an unused assignment behind the loop.
- * delete those insns.
- */
- static unsigned
- opt_elim_dead_assign (void)
- {
- unsigned change_count = 0;
-- for (unsigned index = 0; index + 1 < insns.size (); ++index)
-+ for (int index = insns.size () - 1; index >= 0; --index)
- {
- rtx_insn * insn = insns[index];
- if (!NONJUMP_INSN_P(insn))
-@@ -2186,10 +2210,6 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
-- // df_set_flags (df_LR_RUN_DCE + df_DEFER_INSN_RESCAN);
-- // df_note_add_problem ();
-- // df_analyze ();
--
- be_verbose = strchr (string_bbb_opts, 'v');
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
-
-From b02fdbd28177c393c37b5de2448b1a9506a14f82 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 26 Apr 2017 17:50:10 +0200
-Subject: [PATCH 094/303] @B fixed opt_const_cmp_to_sub
-
----
- gcc/bbb-opts.c | 81 ++++++++++++++++++++++++----------------------------------
- 1 file changed, 34 insertions(+), 47 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 9d138063fb27..f0e2f7b58d4c 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1491,8 +1491,8 @@ opt_const_cmp_to_sub (void)
- if (!setp)
- continue;
-
-- rtx dstp = SET_DEST(setp);
-- if (!REG_P(dstp))
-+ rtx constant_reg = SET_DEST(setp);
-+ if (!REG_P(constant_reg))
- continue;
-
- rtx srcp = SET_SRC(setp);
-@@ -1503,34 +1503,20 @@ opt_const_cmp_to_sub (void)
- if (intval < -8 || intval > 7 || intval == 0)
- continue;
-
-- enum machine_mode mode = GET_MODE(dstp);
-+ enum machine_mode mode = GET_MODE(constant_reg);
- if (GET_MODE_SIZE(mode) > 4)
- continue;
-
- // printf("mode size: %d\n", GET_MODE_SIZE(mode));
-
-- rtx reg = dstp == left ? right : left;
-- rtx plus = gen_rtx_PLUS(mode, copy_reg (reg, -1), gen_rtx_CONST_INT (mode, intval));
--
-- rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(copy_reg (reg, -1), plus));
-+ rtx reg = constant_reg == left ? right : constant_reg == right ? left : 0;
-
-- int num_clobbers_to_add = 0;
-- int insn_code_number = recog (PATTERN (neuprev), neuprev, &num_clobbers_to_add);
-- if (insn_code_number < 0 || !check_asm_operands (PATTERN (neuprev)))
-+ // no gain with address regs.
-+ if (!reg || REGNO(reg) > 7)
- continue;
-
-- // also convert current statement to cmp #0, reg
-- SET_INSN_DELETED(insn);
-- rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, copy_reg(reg, -1), gen_rtx_CONST_INT(mode, 0)));
-- insn = emit_insn_after (neu, prev);
-- add_reg_note (insn, REG_DEAD, reg);
--
-- SET_INSN_DELETED(prev);
-- prev = emit_insn_before (PATTERN (neuprev), insn);
--
-- log ("const_cmp_to_sub replaced reg-reg compare with sub\n");
--
-- if (dstp != left)
-+ // search the jump(s)
-+ bool ok = true;
- {
- // invert all conditions using this statement.
- std::vector<unsigned> todo;
-@@ -1538,7 +1524,7 @@ opt_const_cmp_to_sub (void)
- done.resize (insns.size ());
- todo.push_back (index + 1);
-
-- while (todo.size ())
-+ while (ok && todo.size ())
- {
- unsigned pos = todo[todo.size () - 1];
- todo.pop_back ();
-@@ -1555,7 +1541,7 @@ opt_const_cmp_to_sub (void)
- todo.push_back (pos + 1);
-
- rtx_insn * patchme = insns[pos];
-- if (!JUMP_P(insn))
-+ if (!JUMP_P(patchme))
- continue;
-
- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(patchme));
-@@ -1569,32 +1555,33 @@ opt_const_cmp_to_sub (void)
- {
- rtx condition = XEXP(jmpsrc, 0);
- RTX_CODE code = GET_CODE(condition);
-- RTX_CODE newcode = code;
-- if (code == GE)
-- newcode = LE;
-- else if (code == GT)
-- newcode = LT;
-- else if (code == LT)
-- newcode = GT;
-- else if (code == LE)
-- newcode = GE;
-- else if (code == GEU)
-- newcode = LEU;
-- else if (code == GTU)
-- newcode = LTU;
-- else if (code == LTU)
-- newcode = GTU;
-- else if (code == LEU)
-- newcode = GEU;
--
-- if (code != newcode)
-- {
-- log ("patch jcc %d -> %d\n", code, newcode);
-- XEXP(jmpsrc, 0) = gen_rtx_fmt_ee(newcode, VOIDmode, XEXP(condition, 0), XEXP(condition, 1));
-- }
-+ ok = code == EQ || code == NE;
- }
- }
- }
-+ if (!ok)
-+ continue;
++/* 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
+
-+ rtx plus = gen_rtx_PLUS(mode, copy_reg (reg, -1), gen_rtx_CONST_INT (mode, intval));
++/* We use A4 for the PIC pointer, not A5, which is the framepointer. */
+
-+ rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(copy_reg (reg, -1), plus));
++#undef PIC_OFFSET_TABLE_REGNUM
++#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
++
++/* 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. */
+
-+ int num_clobbers_to_add = 0;
-+ int insn_code_number = recog (PATTERN (neuprev), neuprev, &num_clobbers_to_add);
-+ if (insn_code_number < 0 || !check_asm_operands (PATTERN (neuprev)))
-+ continue;
++#undef FRAME_POINTER_REGNUM
++#define FRAME_POINTER_REGNUM 13
+
-+ // also convert current statement to cmp #0, reg
-+ SET_INSN_DELETED(insn);
-+ rtx copyreg = copy_reg (reg, -1);
-+ rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, copyreg, gen_rtx_CONST_INT(mode, 0)));
-+ insn = emit_insn_after (neu, prev);
-+ add_reg_note (insn, REG_DEAD, copyreg);
++#undef M68K_REGNAME
++#define M68K_REGNAME(r) (reg_names[(r)])
+
-+ SET_INSN_DELETED(prev);
-+ prev = emit_insn_before (PATTERN (neuprev), insn);
++/* The AmigaOS ABI does not define how structures should be returned, so,
++ contrary to 'm68k.h', we prefer a multithread-safe solution. */
+
-+ log ("const_cmp_to_sub replaced reg-reg compare with sub\n");
-
- ++change_count;
- }
-
-From 67cc3de981f1498e225257ccd4783452e127e58c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 26 Apr 2017 20:21:59 +0200
-Subject: [PATCH 095/303] @B fix NPE
-
----
- gcc/bbb-opts.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f0e2f7b58d4c..ceb548bea823 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1551,7 +1551,9 @@ opt_const_cmp_to_sub (void)
- rtx jmppattern = PATTERN (patchme);
-
- rtx jmpsrc = XEXP(jmppattern, 1);
-- if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-+ if (!jmpsrc)
-+ ok = false;
-+ else if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
- {
- rtx condition = XEXP(jmpsrc, 0);
- RTX_CODE code = GET_CODE(condition);
-
-From 17dff22094612ae1f122eec1dad72583a677c1e3 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 27 Apr 2017 17:25:51 +0200
-Subject: [PATCH 096/303] @R some better encapsulation, @D add reg usage to asm
- source use 'V'
-
----
- gcc/bbb-opts.c | 421 +++++++++++++++++++++++++++++++++++----------------------
- gcc/final.c | 7 +
- 2 files changed, 264 insertions(+), 164 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index ceb548bea823..32b1aed86ae5 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -66,14 +66,17 @@
- #include "tree.h"
- #include "tree-pass.h"
- #include "conditions.h"
--#include "cselib.h"
- #include "langhooks.h"
- #include <vector>
- #include <set>
- #include <map>
-
--static bool be_verbose;
-+bool be_very_verbose;
-+bool be_verbose;
-
-+#ifdef __ECLIPSE__
-+extern char * string_bbb_opts;
-+#endif
- extern struct lang_hooks lang_hooks;
-
- /* Lookup of the current function name. */
-@@ -116,86 +119,102 @@ log (char const * fmt, ...)
- *
- * Track use & def separate to determine starting points.
- */
--struct insn_info
-+class insn_info
- {
-- unsigned _use; // bit set if registers are used
-- unsigned _def; // bit set if registers are defined
-- unsigned _hard; // bit set if registers can't be renamed
--
-- insn_info () :
-- _use (0), _def (0), _hard (0)
-+ rtx_insn * insn; // the insn
-+ unsigned myuse; // bit set if registers are used in this statement
-+ unsigned mydef; // bit set if registers are set in this statement
-+ unsigned hard; // bit set if registers can't be renamed
-+ unsigned use; // bit set if registers are used in program flow
-+ unsigned def; // bit set if registers are defined in program flow
++#undef PCC_STATIC_STRUCT_RETURN
+
-+public:
-+ insn_info (rtx_insn * i = 0) :
-+ insn (i), myuse (0), mydef (0), hard (0), use (0), def (0)
- {
- }
-
- inline void
- reset ()
- {
-- _use = 0;
-- _def = 0;
-- _hard = 0;
-+ use = 0;
-+ def = 0;
-+ hard = 0;
-+ }
++/* 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)). */
+
-+ inline bool
-+ is_empty ()
-+ {
-+ return !def && !use && !hard;
- }
-
- inline void
-- use (int regno)
-+ mark_use (int regno)
- {
-- _use |= 1 << regno;
-+ myuse |= 1 << regno;
-+ use |= 1 << regno;
- }
-
- inline void
-- def (int regno)
-+ mark_def (int regno)
- {
-- _def |= 1 << regno;
-+ mydef |= 1 << regno;
-+ def |= 1 << regno;
- }
-
- inline void
-- hard (int regno)
-+ mark_hard (int regno)
- {
-- _hard |= 1 << regno;
-+ hard |= 1 << regno;
- }
-
- inline void
- unset (int regno)
- {
-- _use &= ~(1 << regno);
-- _def &= ~(1 << regno);
-- _hard &= ~(1 << regno);
-+ use &= ~(1 << regno);
-+ def &= ~(1 << regno);
-+ hard &= ~(1 << regno);
-+ }
++//+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.
++//+
+
-+ inline unsigned
-+ get_use () const
-+ {
-+ return use;
-+ }
-+ inline unsigned
-+ get_def () const
-+ {
-+ return def;
-+ }
-+ inline unsigned
-+ get_hard () const
-+ {
-+ return hard;
- }
-
- inline bool
- is_use (int regno)
- {
-- return (_use & (1 << regno)) != 0;
-+ return (use & (1 << regno)) != 0;
- }
-
- inline bool
- is_def (int regno)
- {
-- return (_def & (1 << regno)) != 0;
-+ return (def & (1 << regno)) != 0;
- }
-
- inline bool
- is_hard (int regno)
- {
-- return (_hard & (1 << regno)) != 0;
-- }
--
-- inline insn_info
-- operator | (insn_info const & o) const
-- {
-- insn_info t;
-- t._use = _use | o._use;
-- t._def = _def | o._def;
-- t._hard = _hard | o._hard;
-- return t;
-+ return (hard & (1 << regno)) != 0;
- }
-
-- inline insn_info &
-- operator |= (insn_info const & o)
-+ inline void
-+ clear_hard_def ()
- {
-- _use |= o._use;
-- _def |= o._def;
-- _hard |= o._hard;
-- return *this;
-+ hard = 0;
-+ def = 0;
- }
-
- /*
-@@ -208,106 +227,155 @@ struct insn_info
- inline void
- updateWith (insn_info const & o)
- {
-- _use &= ~o._def;
-- _use |= o._use;
-- _def = 0;
-+ use &= ~o.def;
-+ use |= o.use;
-+ def = 0;
- }
-
-- inline bool
-- operator == (insn_info const & o)
-+ inline insn_info &
-+ merge (insn_info const & o)
- {
-- return _use == o._use;
-+ use = (use & ~o.def) | o.use;
-+ def |= o.def;
-+ hard |= o.hard;
-+ return *this;
-+ }
++//poison VAR
++//#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
+
-+ inline insn_info &
-+ drop_def ()
-+ {
-+ use &= ~def;
-+ return *this;
- }
-
-+#if 0
-+ inline insn_info
-+ operator | (insn_info const & o) const
-+ {
-+ insn_info t;
-+ t.use = use | o.use;
-+ t.def = def | o.def;
-+ t.hard = hard | o.hard;
-+ return t;
-+ }
++#undef WCHAR_TYPE
++#define WCHAR_TYPE "unsigned short"
+
-+ inline bool
-+ operator == (insn_info const & o)
-+ {
-+ return use == o.use;
-+ }
++/* XXX: section support */
++#if 0
++/* 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
+
- inline insn_info
- operator ~ () const
-+ {
-+ insn_info t;
-+ t.use = ~use;
-+ t.def = ~def;
-+ t.hard = ~hard;
-+ return t;
-+ }
++#undef TARGET_ASM_EH_FRAME_SECTION
++#define TARGET_ASM_EH_FRAME_SECTION amiga_eh_frame_section
+#endif
+
-+ inline insn_info &
-+ make_hard ()
-+ {
-+ hard = use | def;
-+ return *this;
-+ }
++/* Use sjlj exceptions because dwarf work only on elf targets */
++#undef DWARF2_UNWIND_INFO
++#define DWARF2_UNWIND_INFO 0
+
-+ inline insn_info &
-+ make_clobber ()
- {
-- insn_info t;
-- t._use = ~_use;
-- t._def = ~_def;
-- t._hard = ~_hard;
-- return t;
-+ hard = use = def = use | def;
-+ return *this;
- }
-
- inline bool
- contains (insn_info const & o) const
- {
-- if (o._def & ~_def)
-+ if (o.def & ~def)
- return false;
-- if (o._use & ~_use)
-+ if (o.use & ~use)
- return false;
-- if (o._hard & ~_hard)
-+ if (o.hard & ~hard)
- return false;
- return true;
- }
-
- void
-- scan_call (rtx_insn *);
-+ scan ();
-
- void
-- scan (rtx);
-+ scan_rtx (rtx);
-
- /* return bits for alternate free registers. */
- unsigned
- get_free_mask () const
- {
-- if (_def & _hard)
-+ if (def & hard)
- return 0;
-
-- if (!_def || _def > 0x1000)
-+ if (!def || def > 0x1000)
- return 0;
-
-- unsigned mask = _def - 1;
-+ unsigned mask = def - 1;
- /* more than one register -> don't touch. */
-- if ((mask & ~_def) != mask)
-+ if ((mask & ~def) != mask)
- return 0;
-
-- if (_def > 0xff)
-+ if (def > 0xff)
- mask &= 0xff00;
-
-- return mask & ~_use;
-+ return mask & ~use;
-+ }
+
-+ unsigned
-+ get_regbit () const
-+ {
-+ return def & ~hard & ~use & 0x7fff;
- }
- };
-
- void
--insn_info::scan_call (rtx_insn * insn)
-+insn_info::scan ()
- {
-- /* add mregparm registers. */
-- for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
-+ rtx pattern = PATTERN (insn);
-+ if (CALL_P(insn))
- {
-- rtx op, reg;
-+ /* add mregparm registers. */
-+ for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
-+ {
-+ rtx op, reg;
-
-- if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-- for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
-- use (r);
-+ if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-+ for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
-+ mark_use (r);
-+ }
-+ /* mark scratch registers. */
-+ mark_def (0);
-+ mark_def (1);
-+ mark_def (8);
-+ mark_def (9);
-+ /* also mark all registers as not renamable */
-+ hard = use;
- }
-- /* also mark all registers as not renamable */
-- _hard = _use;
--
-- scan (PATTERN (insn));
--
-- /* mark scratch registers. */
-- def (0);
-- def (1);
-- def (8);
-- def (9);
--
-+ scan_rtx (pattern);
- }
-
- /* scan rtx for registers and set the corresponding flags. */
- void
--insn_info::scan (rtx x)
-+insn_info::scan_rtx (rtx x)
- {
- if (REG_P(x))
- {
- for (int n = REG_NREGS(x), r = REGNO(x); n > 0; --n, ++r)
-- use (r);
-+ mark_use (r);
- return;
- }
-
- if (x == cc0_rtx)
- {
-- use (FIRST_PSEUDO_REGISTER);
-+ mark_use (FIRST_PSEUDO_REGISTER);
- return;
- }
-
-@@ -316,17 +384,17 @@ insn_info::scan (rtx x)
- /* handle SET and record use and def. */
- if (code == SET)
- {
-- unsigned u = _use;
-- scan (SET_DEST(x));
-+ unsigned u = use;
-+ scan_rtx (SET_DEST(x));
- if (REG_P(SET_DEST(x)))
- {
-- _def |= _use;
-- _use = u;
-+ def |= use;
-+ use = u;
- }
-- scan (SET_SRC(x));
-+ scan_rtx (SET_SRC(x));
- int code = GET_CODE(SET_SRC(x));
- if (code == ASM_OPERANDS)
-- _use = _hard |= _def | _use;
-+ use = hard |= def | use;
- return;
- }
-
-@@ -334,10 +402,10 @@ insn_info::scan (rtx x)
- for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
-- scan (XEXP(x, i));
-+ scan_rtx (XEXP(x, i));
- else if (fmt[i] == 'E')
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-- scan (XVECEXP(x, i, j));
-+ scan_rtx (XVECEXP(x, i, j));
- }
- }
-
-@@ -429,7 +497,7 @@ is_reg_dead (unsigned regno, unsigned _pos)
- {
- insn_info & ii0 = infos[pos];
- // skip entries without info
-- if (!ii0._def && !ii0._use && !ii0._hard)
-+ if (ii0.is_empty ())
- continue;
-
- // not dead if usage is reported in the next statement
-@@ -438,6 +506,45 @@ is_reg_dead (unsigned regno, unsigned _pos)
- return true;
- }
-
-+/* helper stuff to enhance the asm output. */
-+int my_flag_regusage;
-+void
-+append_reg_usage (FILE * f, rtx_insn * insn)
-+{
++/* This is how to output an assembler line that says to advance the
++ location counter to a multiple of 2**LOG bytes. */
+
-+ auto i = insn2index.find (insn);
-+ if (i == insn2index.end ())
-+ return;
++#ifndef ALIGN_ASM_OP
++#define ALIGN_ASM_OP "\t.align\t"
++#endif
+
-+ insn_info & ii = infos[i->second];
++/* 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)
+
-+ fprintf (f, "\n\t\t\t\t\t\t| ");
++#if 0
+
-+ for (int j = 0; j < 8; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
-+ fprintf (f, "d%d ", j);
-+ }
-+ else
-+ fprintf (f, " ");
++/* 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).
+
-+ for (int j = 8; j < 16; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
-+ fprintf (f, "a%d ", j - 8);
-+ }
-+ else
-+ fprintf (f, " ");
++ 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'.
+
-+ if (ii.is_use (FIRST_PSEUDO_REGISTER))
-+ fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc ");
++ 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. */
+
- /*
- * Helper function to dump the code.
- * Sometimes used during debugging.
-@@ -456,33 +563,7 @@ dump_insns (char const * name, bool all)
- fprintf (stderr, "%d: ", i);
-
- if (i < infos.size ())
-- {
-- insn_info & ii = infos[i];
--
-- for (int j = 0; j < 8; ++j)
-- if (ii.is_use (j) || ii.is_def (j))
-- {
-- if (ii.is_hard (j))
-- fprintf (stderr, "!");
-- if (ii.is_def (j))
-- fprintf (stderr, "*");
-- fprintf (stderr, "d%d ", j);
-- }
--
-- for (int j = 8; j < 16; ++j)
-- if (ii.is_use (j) || ii.is_def (j))
-- {
-- if (ii.is_hard (j))
-- fprintf (stderr, "!");
-- if (ii.is_def (j))
-- fprintf (stderr, "*");
-- fprintf (stderr, "a%d ", j - 8);
-- }
--
-- if (ii.is_use (FIRST_PSEUDO_REGISTER))
-- fprintf (stderr, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc ");
--
-- }
-+ append_reg_usage (stderr, insns[i]);
-
- fprintf (stderr, "\t");
- debug_rtx (insns[i]);
-@@ -569,8 +650,8 @@ update_insn_infos (void)
- if (pass && infos[pos].contains (ii))
- break;
-
-- ii._hard = 0;
-- ii |= infos[pos];
-+ ii.clear_hard_def ();
-+ ii.merge (infos[pos]);
-
- if (LABEL_P(insn))
- {
-@@ -591,10 +672,11 @@ update_insn_infos (void)
-
- if (CALL_P(insn))
- {
-- insn_info use;
-- use.scan_call (insn);
-+ insn_info use (insn);
-+ use.scan ();
-
-- infos[pos] = use | ii;
-+ ii.merge (use);
-+ infos[pos] = ii;
- ii.updateWith (use);
-
- continue;
-@@ -602,7 +684,7 @@ update_insn_infos (void)
-
- if (JUMP_P(insn))
- {
-- insn_info use;
-+ insn_info use (insn);
- if (ANY_RETURN_P(pattern))
- {
- tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-@@ -610,19 +692,20 @@ update_insn_infos (void)
- // log ("return size %d\n", sz);
- if (sz <= 64)
- {
-- use.hard (0);
-- use.use (0);
-+ use.mark_hard (0);
-+ use.mark_use (0);
- if (sz > 32)
- {
-- use.hard (1);
-- use.use (1);
-+ use.mark_hard (1);
-+ use.mark_use (1);
- }
- }
- ii.reset ();
- }
-
-- use.scan (pattern);
-- infos[pos] = use | ii;
-+ use.scan ();
-+ ii.merge (use);
-+ infos[pos] = ii;
- ii.updateWith (use);
-
- continue;
-@@ -630,31 +713,41 @@ update_insn_infos (void)
-
- if (GET_CODE (pattern) == USE)
- {
-- rtx x = XEXP(pattern, 0);
-- if (REG_P(x))
-- {
-- ii.use (REGNO(x));
-- ii.hard (REGNO(x));
-- }
-+ insn_info use (insn);
-+ use.scan ();
-+ use.make_clobber ();
++#undef TARGET_ENCODE_SECTION_INFO
++#define TARGET_ENCODE_SECTION_INFO amigaos_encode_section_info
+
-+ ii.merge (use);
- infos[pos] = ii;
-+ ii.updateWith (use);
-+
-+// rtx x = XEXP(pattern, 0);
-+// if (REG_P(x))
-+// {
-+// ii.mark_use (REGNO(x));
-+// ii.mark_hard (REGNO(x));
-+// }
-+// infos[pos] = ii;
- continue;
- }
-
- if (GET_CODE (pattern) == CLOBBER)
- {
- /* mark regs as use and def */
-- insn_info use;
-- use.scan (pattern);
-- use._hard = use._use = use._def = use._use | use._def;
-- infos[pos] = use | ii;
-+ insn_info use (insn);
-+ use.scan ();
-+ use.make_clobber ();
-+ ii.merge (use);
-+ infos[pos] = ii;
- ii.updateWith (use);
- continue;
- }
-
-- insn_info use;
-- use.scan (pattern);
-+ insn_info use (insn);
-+ use.scan ();
++#define LIBCALL_ENCODE_SECTION_INFO(FUN) \
++do \
++ { \
++ if (flag_pic >= 3) \
++ SYMBOL_REF_FLAG (FUN) = 1; \
++ } \
++while (0)
+
- if (single_set (insn) == 0)
-- use._hard = use._use | use._def;
-+ use.make_hard ();
- else
- /* if not cc0 defined check for mod. */
- if (!use.is_def (FIRST_PSEUDO_REGISTER))
-@@ -662,15 +755,15 @@ update_insn_infos (void)
- CC_STATUS_INIT;
- NOTICE_UPDATE_CC(PATTERN (insn), insn);
- if (cc_status.value1 || cc_status.value2)
-- use.def (FIRST_PSEUDO_REGISTER);
-+ use.mark_def (FIRST_PSEUDO_REGISTER);
- }
-
- /* mark not renameable in prologue/epilogue. */
- if (proepilogue[pos])
-- use._hard = use._use | use._def;
-+ use.make_hard ();
-
-- ii._use &= ~use._def;
-- infos[pos] = use | ii;
-+ ii.merge (use);
-+ infos[pos] = ii;
- ii.updateWith (use);
- }
- ++pass;
-@@ -699,12 +792,12 @@ is_reg_touched_between (unsigned regno, int from, int to)
- {
- for (int index = from + 1; index < to; ++index)
- {
-- insn_info ii;
- rtx_insn * insn = insns[index];
-+ insn_info ii (insn);
- if (CALL_P(insn))
-- ii.scan_call (insn);
-+ ii.scan ();
- else
-- ii.scan (PATTERN (insn));
-+ ii.scan_rtx (PATTERN (insn));
- if (ii.is_use (regno) || ii.is_def (regno))
- return true;
- }
-@@ -754,7 +847,7 @@ opt_reg_rename (void)
- insn_info & ii = infos[index];
-
- /* do not rename if register is hard or used in same statement. */
-- const unsigned rename_regbit = ii._def & ~ii._hard & ~ii._use;
-+ const unsigned rename_regbit = ii.get_regbit ();
- if (!rename_regbit)
- continue;
-
-@@ -819,7 +912,7 @@ opt_reg_rename (void)
- insn_info & jj = infos[pos];
-
- /* marked as hard reg -> invalid rename */
-- if (jj._use & jj._hard & rename_regbit)
-+ if (jj.get_use () & jj.get_hard () & rename_regbit)
- mask = 0;
-
- // /* defined again -> invalid rename */
-@@ -830,16 +923,16 @@ opt_reg_rename (void)
- break;
-
- /* not used. and not a def */
-- if (pos == runpos && (jj._def & rename_regbit))
-+ if (pos == runpos && (jj.get_def () & rename_regbit))
- {
- /* continue since this pos was added by start search. */
- }
-- else if (!(jj._use & rename_regbit))
-+ else if (!(jj.get_use () & rename_regbit))
- break;
-
- /* update free regs. */
-- mask &= ~jj._use;
-- mask &= ~jj._def;
-+ mask &= ~jj.get_use ();
-+ mask &= ~jj.get_def ();
- if (!mask)
- break;
-
-@@ -1616,7 +1709,7 @@ opt_elim_dead_assign (void)
-
- if (is_reg_dead (REGNO(dst), index))
- {
-- log ("elim_dead_assign to %s\n", reg_names[REGNO(dst)]);
-+ log ("%d: elim_dead_assign to %s\n", index, reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
- ++change_count;
- }
-@@ -1897,9 +1990,9 @@ opt_shrink_stack_frame (void)
- continue;
-
- insn_info & jj = infos[i];
-- ii |= jj;
-+ ii.merge (jj);
- }
-- unsigned freemask = ~ii._use;
-+ unsigned freemask = ~ii.get_use ();
-
- rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
- rtx a5 = gen_raw_REG (SImode, FRAME_POINTER_REGNUM);
-@@ -2123,9 +2216,9 @@ opt_shrink_stack_frame (void)
- continue;
-
- insn_info & jj = infos[i];
-- ii |= jj;
-+ ii.merge (jj);
- }
-- unsigned freemask = ~ii._use;
-+ unsigned freemask = ~ii.get_use ();
-
- if (freemask & (1 << FRAME_POINTER_REGNUM))
- {
-@@ -2199,7 +2292,8 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
-- be_verbose = strchr (string_bbb_opts, 'v');
-+ be_very_verbose = strchr (string_bbb_opts, 'V');
-+ be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v');
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-@@ -2257,7 +2351,6 @@ namespace
-
- if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
- dump_insns ("bbb", strchr (string_bbb_opts, 'X'));
-- clear ();
-
- return 0;
- }
-diff --git a/gcc/final.c b/gcc/final.c
-index 31f9b4815d75..94c96470e019 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -2151,6 +2151,7 @@ call_from_call_insn (rtx_call_insn *insn)
- SEEN is used to track the end of the prologue, for emitting
- debug information. We force the emission of a line note after
- both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */
-+rtx_insn * current_insn;
-
- rtx_insn *
- final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
-@@ -2160,6 +2161,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
- rtx set;
- #endif
- rtx_insn *next;
-+ current_insn = insn;
-
- insn_counter++;
-
-@@ -3622,6 +3624,8 @@ do_assembler_dialects (const char *p, int *dialect)
- void
- output_asm_insn (const char *templ, rtx *operands)
- {
-+ extern bool be_very_verbose;
-+ extern void append_reg_usage(FILE *, rtx_insn *);
- const char *p;
- int c;
- #ifdef ASSEMBLER_DIALECT
-@@ -3778,6 +3782,9 @@ output_asm_insn (const char *templ, rtx *operands)
- putc (c, asm_out_file);
- }
-
-+ if (be_very_verbose)
-+ append_reg_usage(asm_out_file, current_insn);
++/* Select and switch to a section for EXP. */
+
- /* Write out the variable names for operands, if we know them. */
- if (flag_verbose_asm)
- output_asm_operand_names (operands, oporder, ops);
-
-From c61d5d9c3e2f1376ab8f4a9783a1fc5e9c283f3c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 27 Apr 2017 22:27:45 +0200
-Subject: [PATCH 097/303] @R some better encapsulation
-
----
- gcc/bbb-opts.c | 136 ++++++++++++++++++---------------------------------------
- 1 file changed, 43 insertions(+), 93 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 32b1aed86ae5..439223bf6f87 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -123,14 +123,13 @@ class insn_info
- {
- rtx_insn * insn; // the insn
- unsigned myuse; // bit set if registers are used in this statement
-- unsigned mydef; // bit set if registers are set in this statement
- unsigned hard; // bit set if registers can't be renamed
- unsigned use; // bit set if registers are used in program flow
-- unsigned def; // bit set if registers are defined in program flow
-+ unsigned def; // bit set if registers are defined here
-
- public:
- insn_info (rtx_insn * i = 0) :
-- insn (i), myuse (0), mydef (0), hard (0), use (0), def (0)
-+ insn (i), myuse (0), hard (0), use (0), def (0)
- {
- }
-
-@@ -158,7 +157,6 @@ class insn_info
- inline void
- mark_def (int regno)
- {
-- mydef |= 1 << regno;
- def |= 1 << regno;
- }
-
-@@ -198,6 +196,12 @@ class insn_info
- return (use & (1 << regno)) != 0;
- }
-
-+ inline bool
-+ is_myuse (int regno)
-+ {
-+ return (myuse & (1 << regno)) != 0;
-+ }
++//#undef TARGET_ASM_SELECT_SECTION
++//#define TARGET_ASM_SELECT_SECTION amigaos_select_section
+
- inline bool
- is_def (int regno)
- {
-@@ -340,7 +344,23 @@ void
- insn_info::scan ()
- {
- rtx pattern = PATTERN (insn);
-- if (CALL_P(insn))
-+ if (ANY_RETURN_P(pattern))
-+ {
-+ tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-+ int sz = type ? TREE_INT_CST_LOW(type) : 0;
-+ // log ("return size %d\n", sz);
-+ if (sz <= 64)
-+ {
-+ mark_hard (0);
-+ mark_use (0);
-+ if (sz > 32)
-+ {
-+ mark_hard (1);
-+ mark_use (1);
-+ }
-+ }
-+ }
-+ else if (CALL_P(insn))
- {
- /* add mregparm registers. */
- for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
-@@ -385,11 +405,13 @@ insn_info::scan_rtx (rtx x)
- if (code == SET)
- {
- unsigned u = use;
-+ unsigned mu = myuse;
- scan_rtx (SET_DEST(x));
- if (REG_P(SET_DEST(x)))
- {
- def |= use;
- use = u;
-+ myuse = mu;
- }
- scan_rtx (SET_SRC(x));
- int code = GET_CODE(SET_SRC(x));
-@@ -518,13 +540,14 @@ append_reg_usage (FILE * f, rtx_insn * insn)
-
- insn_info & ii = infos[i->second];
-
-- fprintf (f, "\n\t\t\t\t\t\t| ");
-+ if (f != stderr)
-+ fprintf (f, "\n\t\t\t\t\t\t| ");
-
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j) || ii.is_def (j))
- {
- fprintf (f, ii.is_hard (j) ? "!" : " ");
-- fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
- fprintf (f, "d%d ", j);
- }
- else
-@@ -534,14 +557,14 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- if (ii.is_use (j) || ii.is_def (j))
- {
- fprintf (f, ii.is_hard (j) ? "!" : " ");
-- fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
- fprintf (f, "a%d ", j - 8);
- }
- else
- fprintf (f, " ");
-
- if (ii.is_use (FIRST_PSEUDO_REGISTER))
-- fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc ");
-+ fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "+cc " : " cc ");
-
- }
-
-@@ -669,84 +692,24 @@ update_insn_infos (void)
- }
-
- rtx pattern = PATTERN (insn);
-+ insn_info use (insn);
-+ use.scan ();
-
- if (CALL_P(insn))
- {
-- insn_info use (insn);
-- use.scan ();
--
-- ii.merge (use);
-- infos[pos] = ii;
-- ii.updateWith (use);
--
-- continue;
- }
--
-- if (JUMP_P(insn))
-+ else if (JUMP_P(insn))
- {
-- insn_info use (insn);
- if (ANY_RETURN_P(pattern))
- {
-- tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-- int sz = type ? TREE_INT_CST_LOW(type) : 0;
-- // log ("return size %d\n", sz);
-- if (sz <= 64)
-- {
-- use.mark_hard (0);
-- use.mark_use (0);
-- if (sz > 32)
-- {
-- use.mark_hard (1);
-- use.mark_use (1);
-- }
-- }
- ii.reset ();
- }
--
-- use.scan ();
-- ii.merge (use);
-- infos[pos] = ii;
-- ii.updateWith (use);
--
-- continue;
- }
--
-- if (GET_CODE (pattern) == USE)
-- {
-- insn_info use (insn);
-- use.scan ();
-- use.make_clobber ();
--
-- ii.merge (use);
-- infos[pos] = ii;
-- ii.updateWith (use);
--
--// rtx x = XEXP(pattern, 0);
--// if (REG_P(x))
--// {
--// ii.mark_use (REGNO(x));
--// ii.mark_hard (REGNO(x));
--// }
--// infos[pos] = ii;
-- continue;
-- }
--
-- if (GET_CODE (pattern) == CLOBBER)
-+ else if (GET_CODE (pattern) == USE || GET_CODE (pattern) == CLOBBER)
- {
-- /* mark regs as use and def */
-- insn_info use (insn);
-- use.scan ();
- use.make_clobber ();
-- ii.merge (use);
-- infos[pos] = ii;
-- ii.updateWith (use);
-- continue;
- }
--
-- insn_info use (insn);
-- use.scan ();
--
-- if (single_set (insn) == 0)
-+ else if (single_set (insn) == 0)
- use.make_hard ();
- else
- /* if not cc0 defined check for mod. */
-@@ -792,13 +755,8 @@ is_reg_touched_between (unsigned regno, int from, int to)
- {
- for (int index = from + 1; index < to; ++index)
- {
-- rtx_insn * insn = insns[index];
-- insn_info ii (insn);
-- if (CALL_P(insn))
-- ii.scan ();
-- else
-- ii.scan_rtx (PATTERN (insn));
-- if (ii.is_use (regno) || ii.is_def (regno))
-+ insn_info & ii = infos[index];
-+ if (ii.is_myuse (regno) || ii.is_def (regno))
- return true;
- }
- return false;
-@@ -864,10 +822,6 @@ opt_reg_rename (void)
- if (index + 1 < insns.size ())
- todo.push_back (index + 1);
-
--// /* trigger jump checking */
--// if (index > 0 && LABEL_P(insns[index - 1]))
--// todo.push_back (std::make_pair(index - 1, 0));
--
- found.insert (index);
- /* a register was defined, follow all branches. */
- while (mask && todo.size ())
-@@ -913,14 +867,10 @@ opt_reg_rename (void)
-
- /* marked as hard reg -> invalid rename */
- if (jj.get_use () & jj.get_hard () & rename_regbit)
-- mask = 0;
--
--// /* defined again -> invalid rename */
--// if ((jj._def & rename_regbit) && !(jj._use & rename_regbit))
--// mask = 0;
--
-- if (!mask)
-- break;
-+ {
-+ mask = 0;
-+ break;
-+ }
-
- /* not used. and not a def */
- if (pos == runpos && (jj.get_def () & rename_regbit))
-
-From 63bb3cbeae6aa5780413e18a8bfe23873dc310f5 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 27 Apr 2017 23:00:26 +0200
-Subject: [PATCH 098/303] @R some better encapsulation
-
----
- gcc/bbb-opts.c | 228 ++++++++++++++++++++++++++++++---------------------------
- 1 file changed, 120 insertions(+), 108 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 439223bf6f87..fc4acc87a0a9 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -126,11 +126,50 @@ class insn_info
- unsigned hard; // bit set if registers can't be renamed
- unsigned use; // bit set if registers are used in program flow
- unsigned def; // bit set if registers are defined here
-+ int proepi; // 1 = in prologue, 2 = in epilogue, 0 = other
-+ bool stack; // part of stack frame insns
++/* Preserve A4 for baserel code if necessary. */
+
-+ insn_info &
-+ operator = (insn_info const &);
-
- public:
-- insn_info (rtx_insn * i = 0) :
-- insn (i), myuse (0), hard (0), use (0), def (0)
-+ insn_info (rtx_insn * i = 0, int p = 0) :
-+ insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false)
-+ {
-+ }
++#define EXTRA_SAVE_REG(REGNO) \
++do { \
++ if (flag_pic && flag_pic >= 3 && REGNO == PIC_OFFSET_TABLE_REGNUM \
++ && amigaos_restore_a4()) \
++ return true; \
++} while (0)
+
-+ /* update usage. */
-+ void
-+ update (insn_info & o)
-+ {
-+ myuse = o.myuse;
-+ hard = o.hard;
-+ use = o.use;
-+ def = o.def;
-+ }
++/* Predicate for ALTERNATE_PIC_SETUP. */
+
-+ inline rtx_insn *
-+ get_insn () const
-+ {
-+ return insn;
-+ }
++#define HAVE_ALTERNATE_PIC_SETUP (flag_pic >= 3)
+
-+ void
-+ mark_stack ()
-+ {
-+ stack = true;
-+ }
++/* Make a4 point at data hunk. */
+
-+ bool
-+ is_stack () const
-+ {
-+ return stack;
-+ }
++#define ALTERNATE_PIC_SETUP(STREAM) \
++ (amigaos_alternate_pic_setup (STREAM))
+
-+ inline int
-+ in_proepi () const
- {
-+ return proepi;
- }
-
- inline void
-@@ -487,12 +526,9 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- /*
- * Collect some data.
- */
--static std::vector<rtx_insn *> insns;
--static std::vector<char> proepilogue;
--static std::vector<rtx_insn *> temp;
-+static std::vector<insn_info> infos;
- static std::vector<rtx_insn *> jumps;
- static std::map<rtx_insn *, unsigned> insn2index;
--static std::vector<insn_info> infos;
-
- /*
- * Reset collected data.
-@@ -500,8 +536,6 @@ static std::vector<insn_info> infos;
- static void
- clear (void)
- {
-- insns.clear ();
-- proepilogue.clear ();
- jumps.clear ();
- insn2index.clear ();
- infos.clear ();
-@@ -578,23 +612,24 @@ dump_insns (char const * name, bool all)
- fprintf (stderr, "====================================: %s\n", name);
- if (all)
- {
-- for (rtx_insn * insn = get_insns (); insn && insn != insns[0]; insn = NEXT_INSN (insn))
-+ for (rtx_insn * insn = get_insns (); insn && insn != infos[0].get_insn (); insn = NEXT_INSN (insn))
- debug_rtx (insn);
- }
-- for (unsigned i = 0; i < insns.size (); ++i)
-+ for (unsigned i = 0; i < infos.size (); ++i)
- {
- fprintf (stderr, "%d: ", i);
-
-+ rtx_insn * insn = infos[i].get_insn ();
- if (i < infos.size ())
-- append_reg_usage (stderr, insns[i]);
-+ append_reg_usage (stderr, insn);
-
- fprintf (stderr, "\t");
-- debug_rtx (insns[i]);
-+ debug_rtx (insn);
-
- if (all)
- {
-- rtx_insn * p = i + 1 < insns.size () ? insns[i + 1] : 0;
-- for (rtx_insn * q = NEXT_INSN (insns[i]); q && q != p; q = NEXT_INSN (q))
-+ rtx_insn * p = i + 1 < infos.size () ? infos[i + 1].get_insn () : 0;
-+ for (rtx_insn * q = NEXT_INSN (insn); q && q != p; q = NEXT_INSN (q))
- debug_rtx (q);
- }
- }
-@@ -620,9 +655,8 @@ update_insns ()
- if (JUMP_P(insn))
- jumps.push_back (insn);
-
-- insn2index.insert (std::make_pair (insn, insns.size ()));
-- insns.push_back (insn);
-- proepilogue.push_back (inproepilogue);
-+ insn2index.insert (std::make_pair (insn, infos.size ()));
-+ infos.push_back (insn_info (insn, inproepilogue));
-
- if (JUMP_P(insn))
- inproepilogue = 0;
-@@ -647,12 +681,9 @@ update_insns ()
- static void
- update_insn_infos (void)
- {
-- /* prepare insn_info */
-- infos.resize (insns.size ());
--
- /* own analyze reg life */
- std::vector<std::pair<unsigned, insn_info> > todo;
-- todo.push_back (std::make_pair (insns.size () - 1, insn_info ()));
-+ todo.push_back (std::make_pair (infos.size () - 1, insn_info ()));
-
- int pass = 0;
- while (!todo.empty ())
-@@ -664,7 +695,7 @@ update_insn_infos (void)
-
- for (int pos = p.first; pos >= 0; --pos)
- {
-- rtx_insn * insn = insns[pos];
-+ rtx_insn * insn = infos[pos].get_insn ();
- /* can be NULL as used in opt_shrink_stack_frame(). */
- if (!insn)
- continue;
-@@ -679,7 +710,7 @@ update_insn_infos (void)
- if (LABEL_P(insn))
- {
- /* work on all jumps referring to that label. */
-- for (std::vector<rtx_insn *>::iterator i = jumps.begin (); i != jumps.end (); ++i)
-+ for (auto i = jumps.begin (); i != jumps.end (); ++i)
- {
- if (JUMP_LABEL(*i) == insn)
- {
-@@ -722,11 +753,11 @@ update_insn_infos (void)
- }
-
- /* mark not renameable in prologue/epilogue. */
-- if (proepilogue[pos])
-+ if (infos[pos].in_proepi ())
- use.make_hard ();
-
- ii.merge (use);
-- infos[pos] = ii;
-+ infos[pos].update (ii);
- ii.updateWith (use);
- }
- ++pass;
-@@ -778,7 +809,7 @@ find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
- break;
-
- /* do not run over RETURNS */
-- rtx_insn * before = insns[startm1];
-+ rtx_insn * before = infos[startm1].get_insn ();
- if (JUMP_P(before) && ANY_RETURN_P(PATTERN (before)))
- break;
-
-@@ -800,7 +831,7 @@ static unsigned
- opt_reg_rename (void)
- {
- // dump_insns ("rename", 1);
-- for (unsigned index = 0; index < insns.size (); ++index)
-+ for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-
-@@ -819,7 +850,7 @@ opt_reg_rename (void)
- /* first = pos to start, second indicates to treat def as use. */
- std::vector<unsigned> todo;
- std::set<unsigned> found;
-- if (index + 1 < insns.size ())
-+ if (index + 1 < infos.size ())
- todo.push_back (index + 1);
-
- found.insert (index);
-@@ -829,13 +860,13 @@ opt_reg_rename (void)
- unsigned runpos = todo[todo.size () - 1];
- todo.pop_back ();
-
-- for (unsigned pos = runpos; mask && pos < insns.size (); ++pos)
-+ for (unsigned pos = runpos; mask && pos < infos.size (); ++pos)
- {
- /* already searched. */
- if (found.find (pos) != found.end ())
- break;
-
-- rtx_insn * insn = insns[pos];
-+ rtx_insn * insn = infos[pos].get_insn ();
- if (LABEL_P(insn))
- {
- found.insert (pos);
-@@ -844,7 +875,7 @@ opt_reg_rename (void)
- * check if the reg was used at that jump.
- * if used, find def
- */
-- for (std::vector<rtx_insn *>::iterator i = jumps.begin (); i != jumps.end (); ++i)
-+ for (auto i = jumps.begin (); i != jumps.end (); ++i)
- {
- if (JUMP_LABEL(*i) == insn)
- {
-@@ -940,7 +971,7 @@ opt_reg_rename (void)
-
- for (std::set<unsigned>::iterator i = found.begin (); ok && i != found.end (); ++i)
- {
-- rtx_insn * insn = insns[*i];
-+ rtx_insn * insn = infos[*i].get_insn ();
-
- /* temp rename. */
- temp_reg_rename (locs, PATTERN (insn), oldregno, newregno);
-@@ -1044,9 +1075,9 @@ opt_propagate_moves ()
- std::vector<rtx_insn *> jump_out;
-
- /* start at 1 since there must be an insn before the label. */
-- for (unsigned index = 1; index < insns.size (); ++index)
-+ for (unsigned index = 1; index < infos.size (); ++index)
- {
-- rtx_insn * insn = insns[index];
-+ rtx_insn * insn = infos[index].get_insn ();
-
- if (LABEL_P(insn))
- {
-@@ -1103,11 +1134,11 @@ opt_propagate_moves ()
- bool inc = true;
- for (std::vector<unsigned>::iterator j = i + 1; j != reg_reg.end ();)
- {
-- rtx_insn * ii = insns[*i];
-+ rtx_insn * ii = infos[*i].get_insn ();
- rtx seti = single_set (ii);
- rtx srci = SET_SRC(seti);
- rtx dsti = SET_DEST(seti);
-- rtx_insn * jj = insns[*j];
-+ rtx_insn * jj = infos[*j].get_insn ();
- rtx setj = single_set (jj);
- rtx srcj = SET_SRC(setj);
- rtx dstj = SET_DEST(setj);
-@@ -1139,7 +1170,7 @@ opt_propagate_moves ()
-
- for (unsigned k = *i + 1; k != *j; ++k)
- {
-- rtx_insn * check = insns[k];
-+ rtx_insn * check = infos[k].get_insn ();
- if (JUMP_P(check))
- {
- fixups.push_back (fixup);
-@@ -1204,8 +1235,8 @@ opt_propagate_moves ()
- /* got a fixup for all jump_outs? */
- if (fixups.size () == jump_out.size ())
- {
-- rtx_insn * before = insns[current_label_index - 1];
-- rtx_insn * after = insns[index + 1];
-+ rtx_insn * before = infos[current_label_index - 1].get_insn ();
-+ rtx_insn * after = infos[index + 1].get_insn ();
- rtx bset = single_set (before);
-
- log ("propagate_moves condition met, moving regs %s, %s\n",
-@@ -1250,7 +1281,7 @@ opt_propagate_moves ()
- {
- rtx neu = gen_rtx_SET(
- dstj, gen_rtx_PLUS(Pmode, dsti, gen_rtx_CONST_INT(Pmode, fixups[k])));
-- rtx_insn * neui = emit_insn_after (neu, jump_out[k]);
-+ emit_insn_after (neu, jump_out[k]);
- }
- }
- ++change_count;
-@@ -1290,9 +1321,9 @@ opt_strcpy ()
- rtx_insn * reg2x;
- unsigned int regno;
-
-- for (unsigned index = 0; index < insns.size (); ++index)
-+ for (unsigned index = 0; index < infos.size (); ++index)
- {
-- rtx_insn * insn = insns[index];
-+ rtx_insn * insn = infos[index].get_insn ();
-
- if (!NONJUMP_INSN_P(insn))
- {
-@@ -1411,9 +1442,9 @@ opt_commute_add_move (void)
- {
- unsigned change_count = 0;
-
-- for (unsigned index = 0; index + 1 < insns.size (); ++index)
-+ for (unsigned index = 0; index + 1 < infos.size (); ++index)
- {
-- rtx_insn * insn = insns[index];
-+ rtx_insn * insn = infos[index].get_insn ();
- rtx set = single_set (insn);
- if (!set)
- continue;
-@@ -1434,7 +1465,7 @@ opt_commute_add_move (void)
- if (!CONST_INT_P(cnst))
- continue;
-
-- rtx_insn * next = insns[index + 1];
-+ rtx_insn * next = infos[index + 1].get_insn ();
- rtx set2 = single_set (next);
- if (!set2)
- continue;
-@@ -1498,9 +1529,9 @@ opt_const_cmp_to_sub (void)
- {
- unsigned change_count = 0;
- #if HAVE_cc0
-- for (int index = insns.size () - 2; index > 0; --index)
-+ for (int index = infos.size () - 2; index > 0; --index)
- {
-- rtx_insn * insn = insns[index];
-+ rtx_insn * insn = infos[index].get_insn ();
- rtx seti = single_set (insn);
- if (!seti)
- continue;
-@@ -1529,7 +1560,7 @@ opt_const_cmp_to_sub (void)
- continue;
-
- // maybe add a search?
-- rtx_insn * prev = insns[index - 1];
-+ rtx_insn * prev = infos[index - 1].get_insn ();
- rtx setp = single_set (prev);
- if (!setp)
- continue;
-@@ -1564,7 +1595,7 @@ opt_const_cmp_to_sub (void)
- // invert all conditions using this statement.
- std::vector<unsigned> todo;
- std::vector<unsigned> done;
-- done.resize (insns.size ());
-+ done.resize (infos.size ());
- todo.push_back (index + 1);
-
- while (ok && todo.size ())
-@@ -1583,7 +1614,7 @@ opt_const_cmp_to_sub (void)
- if (pos + 1 < infos.size ())
- todo.push_back (pos + 1);
-
-- rtx_insn * patchme = insns[pos];
-+ rtx_insn * patchme = infos[pos].get_insn ();
- if (!JUMP_P(patchme))
- continue;
-
-@@ -1642,9 +1673,9 @@ static unsigned
- opt_elim_dead_assign (void)
- {
- unsigned change_count = 0;
-- for (int index = insns.size () - 1; index >= 0; --index)
-+ for (int index = infos.size () - 1; index >= 0; --index)
- {
-- rtx_insn * insn = insns[index];
-+ rtx_insn * insn = infos[index].get_insn ();
- if (!NONJUMP_INSN_P(insn))
- continue;
-
-@@ -1681,11 +1712,11 @@ static unsigned
- opt_merge_add (void)
- {
- unsigned change_count = 0;
-- for (unsigned index = 0; index + 2 < insns.size (); ++index)
-+ for (unsigned index = 0; index + 2 < infos.size (); ++index)
- {
-- rtx_insn * ins1 = insns[index];
-- rtx_insn * ins2 = insns[index + 1];
-- rtx_insn * ins3 = insns[index + 2];
-+ rtx_insn * ins1 = infos[index].get_insn ();
-+ rtx_insn * ins2 = infos[index + 1].get_insn ();
-+ rtx_insn * ins3 = infos[index + 2].get_insn ();
- if (!NONJUMP_INSN_P(ins1) && !NONJUMP_INSN_P(ins2) && !NONJUMP_INSN_P(ins3))
- continue;
-
-@@ -1738,17 +1769,6 @@ opt_merge_add (void)
- return change_count;
- }
-
--/*
-- * Move the insns back from temp to insns.
-- */
--static void
--clear_temp ()
--{
-- for (unsigned i = 0; i < temp.size (); ++i)
-- if (temp[i])
-- insns[i] = temp[i], temp[i] = 0;
--}
--
- /**
- * 1. scan for all used registers.
- * 2. scan the stack from for omittable push/pop
-@@ -1775,14 +1795,13 @@ static unsigned
- opt_shrink_stack_frame (void)
- {
- /* nothing to do. */
-- if (!insns.size ())
-+ if (!infos.size ())
- return 0;
-
- std::vector<int> a5pos;
-- temp.resize (insns.size ());
-
- unsigned pos = 0;
-- rtx_insn * insn = insns[pos];
-+ rtx_insn * insn = infos[pos].get_insn ();
- if (JUMP_P(insn)) /* return -> empty function*/
- return 0;
-
-@@ -1794,11 +1813,12 @@ opt_shrink_stack_frame (void)
- * Move prologue to temp.
- * Only register push and parallel insn unless its a link a5 are moved.
- */
-- for (; pos < insns.size ();)
-+ for (; pos < infos.size ();)
- {
-- insn = insns[pos];
-+ insn_info & ii = infos[pos];
-+ insn = ii.get_insn ();
-
-- if (proepilogue[pos] != 1)
-+ if (ii.in_proepi () != 1)
- break;
-
- rtx pattern = PATTERN (insn);
-@@ -1817,8 +1837,7 @@ opt_shrink_stack_frame (void)
- else
- {
- /* use movem */
-- temp[pos] = insn;
-- insns[pos] = 0;
-+ ii.mark_stack ();
- }
- ++pos;
- continue;
-@@ -1845,8 +1864,7 @@ opt_shrink_stack_frame (void)
- rtx reg = XEXP(predec, 0);
- if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
- {
-- temp[pos] = insn;
-- insns[pos] = 0;
-+ ii.mark_stack ();
- }
- }
- }
-@@ -1860,9 +1878,8 @@ opt_shrink_stack_frame (void)
- paramstart -= INTVAL(cx);
- }
-
-- if (++pos >= insns.size ())
-+ if (++pos >= infos.size ())
- {
-- clear_temp ();
- return 0;
- }
- }
-@@ -1873,20 +1890,21 @@ opt_shrink_stack_frame (void)
- unsigned prologueend = pos;
-
- /* search epilogues - there can be multiple epilogues. */
-- while (pos < insns.size ())
-+ while (pos < infos.size ())
- {
-- while (pos < insns.size ())
-+ while (pos < infos.size ())
- {
-- if (proepilogue[pos])
-+ if (infos[pos].in_proepi ())
- break;
- ++pos;
- }
-
- /* move epilogues away. */
-- for (; pos < insns.size (); ++pos)
-+ for (; pos < infos.size (); ++pos)
- {
-- insn = insns[pos];
-- if (JUMP_P(insn) || LABEL_P(insn) || !proepilogue[pos])
-+ insn_info & ii = infos[pos];
-+ insn = ii.get_insn ();
-+ if (JUMP_P(insn) || LABEL_P(insn) || !ii.in_proepi ())
- break;
-
- /* omit the frame pointer a5. */
-@@ -1903,8 +1921,7 @@ opt_shrink_stack_frame (void)
- }
-
- /* movem. */
-- temp[pos] = insn;
-- insns[pos] = 0;
-+ ii.mark_stack ();
- }
- else if (GET_CODE(pattern) == SET)
- {
-@@ -1920,10 +1937,7 @@ opt_shrink_stack_frame (void)
- {
- rtx reg = XEXP(postinc, 0);
- if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
-- {
-- temp[pos] = insn;
-- insns[pos] = 0;
-- }
-+ ii.mark_stack ();
- }
- }
- }
-@@ -1936,10 +1950,10 @@ opt_shrink_stack_frame (void)
- insn_info ii;
- for (unsigned i = 0; i < infos.size (); ++i)
- {
-- if (proepilogue[i])
-+ insn_info & jj = infos[i];
-+ if (jj.is_stack ())
- continue;
-
-- insn_info & jj = infos[i];
- ii.merge (jj);
- }
- unsigned freemask = ~ii.get_use ();
-@@ -1949,12 +1963,13 @@ opt_shrink_stack_frame (void)
-
- unsigned adjust = 0;
- /* now all push/pop insns are in temp. */
-- for (unsigned i = 0; i < temp.size (); ++i)
-+ for (unsigned i = 0; i < infos.size (); ++i)
- {
-- insn = temp[i];
-- if (!insn)
-+ insn_info & ii = infos[i];
-+ if (!ii.is_stack ())
- continue;
-
-+ insn = ii.get_insn ();
- rtx pattern = PATTERN (insn);
- /* check the pushed regs, either a vector or single statements */
- if (GET_CODE(pattern) == PARALLEL)
-@@ -2119,9 +2134,10 @@ opt_shrink_stack_frame (void)
- /* fix sp offsets. */
- if (!usea5 && adjust)
- {
-- for (unsigned index = 0; index < insns.size (); ++index)
-+ for (unsigned index = 0; index < infos.size (); ++index)
- {
-- insn = insns[index];
-+ insn_info & ii = infos[index];
-+ insn = ii.get_insn ();
- if (!insn || !INSN_P(insn))
- continue;
-
-@@ -2155,17 +2171,16 @@ opt_shrink_stack_frame (void)
- {
- for (std::vector<int>::iterator i = a5pos.begin (); i != a5pos.end (); ++i)
- {
-- temp[*i] = insns[*i];
-- insns[*i] = 0;
-+ insn_info & ii = infos[*i];
-+ ii.mark_stack ();
- }
-- update_insn_infos ();
-- insn_info ii;
- for (unsigned i = 0; i < infos.size (); ++i)
- {
-- if (proepilogue[i])
-+ insn_info ii;
-+ insn_info & jj = infos[i];
-+ if (jj.is_stack ())
- continue;
-
-- insn_info & jj = infos[i];
- ii.merge (jj);
- }
- unsigned freemask = ~ii.get_use ();
-@@ -2174,13 +2189,10 @@ opt_shrink_stack_frame (void)
- {
- log ("dropping unused frame pointer\n");
- for (std::vector<int>::iterator i = a5pos.begin (); i != a5pos.end (); ++i)
-- SET_INSN_DELETED(temp[*i]);
-+ SET_INSN_DELETED(infos[*i].get_insn ());
- }
- }
-
-- /* restore stack insns */
-- clear_temp ();
--
- return 0;
- }
-
-
-From a882cc15bab5a29c566ccda41663549d87cb0be3 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 28 Apr 2017 11:39:49 +0200
-Subject: [PATCH 099/303] @R optimize opt_merge_add
-
----
- gcc/bbb-opts.c | 370 ++++++++++++++++++++++++++++++++++++++++++++-------------
- 1 file changed, 287 insertions(+), 83 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index fc4acc87a0a9..99c41128e5b8 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -122,22 +122,114 @@ log (char const * fmt, ...)
- class insn_info
- {
- rtx_insn * insn; // the insn
++/* Attribute support. */
+
-+ // usage flags
- unsigned myuse; // bit set if registers are used in this statement
- unsigned hard; // bit set if registers can't be renamed
- unsigned use; // bit set if registers are used in program flow
- unsigned def; // bit set if registers are defined here
++/* Generate the test of d0 before return to set cc register in 'interrupt'
++ function. */
+
- int proepi; // 1 = in prologue, 2 = in epilogue, 0 = other
++#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)
+
- bool stack; // part of stack frame insns
-
-+ // stuff to analyze insns
-+ bool label;
-+ bool jump;
-+ bool call;
-+ bool compare;
-+ bool dst_reg;
-+ bool src_reg;
-+ bool dst_mem;
-+ bool src_mem;
-+ bool dst_plus;
-+ bool src_plus;
-+ bool src_const;
+
-+ int dst_regno;
-+ int dst_mem_reg;
-+ unsigned dst_mem_addr;
++/* Stack checking and automatic extension support. */
+
-+ int src_regno;
-+ int src_mem_regno;
-+ unsigned src_intval;
++#define PROLOGUE_BEGIN_HOOK(STREAM, FSIZE) \
++ (amigaos_prologue_begin_hook ((STREAM), (FSIZE)))
+
- insn_info &
- operator = (insn_info const &);
-
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
-- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false)
-+ insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
-+ false), compare (false), dst_reg (false), src_reg (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (
-+ false), src_const (false), dst_regno (-1), dst_mem_reg (-1), dst_mem_addr (0), src_regno (-1), src_mem_regno (
-+ -1), src_intval (0)
-+ {
-+ }
++#define HAVE_ALTERNATE_FRAME_DESTR_F(FSIZE) \
++ (TARGET_STACKEXTEND && current_function_calls_alloca)
+
-+ inline void
-+ plus_to_move (rtx_insn * newinsn)
-+ {
-+ insn = newinsn;
-+ dst_plus = false;
-+ dst_reg = true;
-+ // usage flags did not change
-+ }
++#define ALTERNATE_FRAME_DESTR_F(STREAM, FSIZE) \
++ (asm_fprintf ((STREAM), "\tjra %U__unlk_a5_rts\n"))
+
-+ inline bool
-+ is_dst_reg () const
-+ {
-+ return dst_reg;
-+ }
++#define HAVE_ALTERNATE_RETURN \
++ (TARGET_STACKEXTEND && frame_pointer_needed && \
++ current_function_calls_alloca)
+
-+ inline bool
-+ is_src_reg () const
-+ {
-+ return src_reg;
-+ }
++#define ALTERNATE_RETURN(STREAM)
+
-+ inline int
-+ get_dst_regno () const
-+ {
-+ return dst_regno;
-+ }
++#if 0
++#define HAVE_restore_stack_nonlocal TARGET_STACKEXTEND
++#define gen_restore_stack_nonlocal gen_stack_cleanup_call
+
-+ inline int
-+ get_src_regno () const
-+ {
-+ return src_regno;
-+ }
++#define HAVE_restore_stack_function TARGET_STACKEXTEND
++#define gen_restore_stack_function gen_stack_cleanup_call
+
-+ inline bool
-+ is_src_plus () const
-+ {
-+ return src_plus;
-+ }
++#define HAVE_restore_stack_block TARGET_STACKEXTEND
++#define gen_restore_stack_block gen_stack_cleanup_call
+
-+ inline bool
-+ is_src_const () const
- {
-+ return src_const;
- }
-
-+ inline void
-+ mark_jump ()
-+ {
-+ jump = true;
-+ }
-+ inline void
-+ mark_call ()
-+ {
-+ call = true;
-+ }
-+ inline void
-+ mark_label ()
-+ {
-+ label = true;
-+ }
++#undef TARGET_ALTERNATE_ALLOCATE_STACK
++#define TARGET_ALTERNATE_ALLOCATE_STACK 1
+
-+ void
-+ fledder (rtx set);
++#define ALTERNATE_ALLOCATE_STACK(OPERANDS) \
++do \
++ { \
++ amigaos_alternate_allocate_stack (OPERANDS); \
++ DONE; \
++ } \
++while (0)
++#endif
+
- /* update usage. */
- void
- update (insn_info & o)
-@@ -470,6 +562,101 @@ insn_info::scan_rtx (rtx x)
- }
- }
-
-+/* read the set and grab infos */
-+void
-+insn_info::fledder (rtx set)
-+{
-+ rtx dst = SET_DEST(set);
-+ rtx src = SET_SRC(set);
++/* begin-GG-local: dynamic libraries */
+
-+ if (dst == cc0_rtx)
-+ {
-+ compare = true;
-+ set = src;
-+ dst = SET_DEST(set);
-+ src = SET_SRC(set);
-+ }
++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 *);
+
-+ if (REG_P(dst))
-+ {
-+ dst_reg = true;
-+ dst_regno = REGNO(dst);
-+ }
-+ else if (MEM_P(dst))
-+ {
-+ dst_mem = true;
-+ rtx mem = XEXP(dst, 0);
-+ if (REG_P(mem))
-+ dst_mem_reg = REGNO(mem);
-+ else if (GET_CODE(mem) == CONST_INT)
-+ dst_mem_addr = INTVAL(mem);
-+ else if (GET_CODE(mem) == PLUS)
-+ {
-+ dst_plus = true;
-+ rtx reg = XEXP(mem, 0);
-+ rtx konst = XEXP(mem, 1);
-+ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-+ {
-+ dst_mem_reg = REGNO(reg);
-+ dst_mem_addr = INTVAL(konst);
-+ }
-+ }
-+ }
++/* This macro is used to check if all collect2 facilities should be used.
++ We need a few special ones, like stripping after linking. */
+
-+ if (REG_P(src))
-+ {
-+ src_reg = true;
-+ src_regno = REGNO(src);
-+ }
-+ else if (MEM_P(src))
-+ {
-+ src_mem = true;
-+ rtx mem = XEXP(src, 0);
-+ if (REG_P(mem))
-+ src_mem_regno = REGNO(mem);
-+ else if (GET_CODE(mem) == CONST_INT)
-+ src_intval = INTVAL(mem);
-+ else if (GET_CODE(mem) == PLUS)
-+ {
-+ src_plus = true;
-+ rtx reg = XEXP(mem, 0);
-+ rtx konst = XEXP(mem, 1);
-+ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-+ {
-+ src_mem_regno = REGNO(reg);
-+ src_const = true;
-+ src_intval = INTVAL(konst);
-+ }
-+ }
-+ }
-+ else if (GET_CODE(src) == CONST_INT)
-+ {
-+ src_const = true;
-+ src_intval = INTVAL(src);
-+ }
-+ else if (GET_CODE(src) == PLUS)
-+ {
-+ src_plus = true;
-+ rtx reg = XEXP(src, 0);
-+ rtx konst = XEXP(src, 1);
-+ if (REG_P(reg))
-+ {
-+ if (GET_CODE(konst) == CONST_INT)
-+ {
-+ src_regno = REGNO(reg);
-+ src_const = true;
-+ src_intval = INTVAL(konst);
-+ }
-+ else if (REG_P(konst))
-+ {
-+ src_reg = true;
-+ src_regno = REGNO(konst);
-+ }
-+ }
-+ }
++#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). */
+
- /* create a copy for a reg. Optional specify a new register number. */
- static rtx
- copy_reg (rtx reg, int newregno)
-@@ -600,6 +787,9 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- if (ii.is_use (FIRST_PSEUDO_REGISTER))
- fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "+cc " : " cc ");
-
-+ if (f == stderr)
-+ fprintf (f, "\n");
++#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG)
+
- }
-
- /*
-@@ -635,43 +825,6 @@ dump_insns (char const * name, bool all)
- }
- }
-
--/*
-- * Create a filtered view of insns - keep only those to work with.
-- */
--static void
--update_insns ()
--{
-- rtx_insn *insn, *next;
-- clear ();
--
-- char inproepilogue = 1;
-- /* create a vector with relevant insn. */
-- for (insn = get_insns (); insn; insn = next)
-- {
-- next = NEXT_INSN (insn);
--
-- if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
-- {
-- if (JUMP_P(insn))
-- jumps.push_back (insn);
--
-- insn2index.insert (std::make_pair (insn, infos.size ()));
-- infos.push_back (insn_info (insn, inproepilogue));
--
-- if (JUMP_P(insn))
-- inproepilogue = 0;
-- }
--
-- if (NOTE_P(insn))
-- {
-- if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-- inproepilogue = 0;
-- else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
-- inproepilogue = 2;
-- }
-- }
--}
--
- /* This is the important function to track register usage plus hard/live state.
- *
- * Start at bottom and work upwards. On all labels trigger all jumps referring to this label.
-@@ -764,6 +917,62 @@ update_insn_infos (void)
- }
- }
-
-+/*
-+ * Create a filtered view of insns - keep only those to work with.
-+ */
-+static void
-+update_insns ()
-+{
-+ rtx_insn *insn, *next;
-+ clear ();
++/* 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. */
+
-+ char inproepilogue = 1;
-+ /* create a vector with relevant insn. */
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
++#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG)
+
-+ if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
-+ {
++/* This macro is called at collect2 exit, to clean everything up. */
+
-+ insn2index.insert (std::make_pair (insn, infos.size ()));
-+ infos.push_back (insn_info (insn, inproepilogue));
-+ insn_info & ii = infos[infos.size () - 1];
++#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup
+
-+ if (JUMP_P(insn))
-+ {
-+ jumps.push_back (insn);
-+ inproepilogue = 0;
++/* 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. */
+
-+ ii.mark_jump ();
-+ }
-+ else if (LABEL_P(insn))
-+ {
-+ ii.mark_label ();
-+ }
-+ else if (CALL_P(insn))
-+ {
-+ ii.mark_call ();
-+ }
-+ else
-+ {
-+ rtx set = single_set (insn);
-+ if (set)
-+ ii.fledder (set);
-+ }
-+ }
++#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
++amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
+
-+ if (NOTE_P(insn))
-+ {
-+ if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-+ inproepilogue = 0;
-+ else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
-+ inproepilogue = 2;
-+ }
-+ }
-+ update_insn_infos ();
-+}
++/* This macro is called just after the first linker invocation, in place of
++ "nm" and "ldd". OUTPUT_FILE is the executable's filename. */
+
- /* convert the lowest set bit into a register number. */
- static int
- bit2regno (unsigned bit)
-@@ -1714,57 +1923,57 @@ opt_merge_add (void)
- unsigned change_count = 0;
- for (unsigned index = 0; index + 2 < infos.size (); ++index)
- {
-- rtx_insn * ins1 = infos[index].get_insn ();
-- rtx_insn * ins2 = infos[index + 1].get_insn ();
-- rtx_insn * ins3 = infos[index + 2].get_insn ();
-- if (!NONJUMP_INSN_P(ins1) && !NONJUMP_INSN_P(ins2) && !NONJUMP_INSN_P(ins3))
-- continue;
-+ insn_info & ii0 = infos[index];
-+ insn_info & ii1 = infos[index + 1];
-+ insn_info & ii2 = infos[index + 2];
-
-- rtx set1 = single_set (ins1);
-- rtx set2 = single_set (ins2);
-- rtx set3 = single_set (ins3);
-- if (!set1 || !set2 || !set3)
-- continue;
-+ if (!ii2.is_dst_reg ())
-+ {
-+ index += 2;
-+ continue;
-+ }
++#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
++/* end-GG-local */
+
-+ if (!ii1.is_dst_reg ())
-+ {
-+ ++index;
-+ continue;
-+ }
-
-- rtx dst1 = SET_DEST(set1);
-- rtx dst2 = SET_DEST(set2);
-- rtx dst3 = SET_DEST(set3);
-- if (!REG_P(dst1) || !REG_P(dst2) || !REG_P(dst3))
-+ if (!ii0.is_dst_reg () || !ii0.is_src_plus () || !ii1.is_src_plus () || !ii2.is_src_plus ())
- continue;
-
-- CC_STATUS_INIT;
-- NOTICE_UPDATE_CC(PATTERN (ins2), ins2);
-- if (cc_status.value1 || cc_status.value2)
-+ if (!ii0.is_src_const () || !ii1.is_src_reg () || !ii2.is_src_const ())
- continue;
-
-- rtx src1 = SET_SRC(set1);
-- rtx src2 = SET_SRC(set2);
-- rtx src3 = SET_SRC(set3);
-- if (GET_CODE(src1) != PLUS || GET_CODE(src2) != PLUS || GET_CODE(src3) != PLUS)
-+ if (ii0.get_dst_regno () != ii1.get_dst_regno () || ii1.get_src_regno () != ii2.get_dst_regno ())
- continue;
-
-- rtx l1 = XEXP(src1, 0);
--// rtx l2 = XEXP(src2, 0);
--// rtx l3 = XEXP(src3, 0);
-+ rtx_insn * insn1 = ii1.get_insn ();
-
-- rtx r1 = XEXP(src1, 1);
-- rtx r2 = XEXP(src2, 1);
-- rtx r3 = XEXP(src3, 1);
-- if (!CONST_INT_P(r1) || !REG_P(r2) || !CONST_INT_P(r3))
-+ CC_STATUS_INIT;
-+ NOTICE_UPDATE_CC(PATTERN (insn1), insn1);
-+ if (cc_status.value1 || cc_status.value2)
- continue;
-
-- if (REGNO(dst1) != REGNO(dst2) || REGNO(r2) != REGNO(dst3))
-- continue;
-+ log ("%d: merge_add applied\n", index);
++#endif
+
-+ rtx_insn * insn0 = ii0.get_insn ();
-+ rtx set = PATTERN (insn0);
-
-- log ("merge_add applied\n");
-+ // convert lea (-1,a0),a1 into move.l a0,a1
-+ rtx_insn * newins0 = make_insn_raw (gen_rtx_SET(XEXP(set, 0), XEXP(XEXP(set, 1), 0)));
-+ add_insn_after (newins0, insn0, 0);
-+ SET_INSN_DELETED(insn0);
-+ // update infos accordingly
-+ ii0.plus_to_move (newins0);
-
-- rtx_insn * newins1 = make_insn_raw (gen_rtx_SET(dst1, l1));
-- add_insn_after (newins1, ins1, 0);
-- SET_INSN_DELETED(ins1);
-+ rtx_insn * insn2 = ii2.get_insn ();
-+ rtx_insn * newins1 = make_insn_raw (PATTERN (insn1));
-+ add_insn_after (newins1, insn2, 0);
-+ SET_INSN_DELETED(insn1);
-+// ii1.swap_adds(newins1, ii2);
-
-- rtx_insn * newins2 = make_insn_raw (PATTERN (ins2));
-- add_insn_after (newins2, ins3, 0);
-- SET_INSN_DELETED(ins2);
-+ ++change_count;
- }
- return change_count;
- }
-@@ -1946,7 +2155,6 @@ opt_shrink_stack_frame (void)
- ++pos;
- }
- /* gather usage stats without prologue/epilogue */
-- update_insn_infos ();
- insn_info ii;
- for (unsigned i = 0; i < infos.size (); ++i)
- {
-@@ -2270,7 +2478,6 @@ namespace
- {
- int done = 1;
- update_insns ();
-- update_insn_infos ();
- if (do_opt_strcpy && opt_strcpy ())
- done = 0, update_insns ();
-
-@@ -2280,22 +2487,20 @@ namespace
- if (do_propagate_moves && opt_propagate_moves ())
- done = 0, update_insns ();
-
-- update_insn_infos ();
- if (do_const_cmp_to_sub && opt_const_cmp_to_sub ())
-- done = 0, update_insns (), update_insn_infos ();
-+ done = 0, update_insns ();
-
- if (do_merge_add && opt_merge_add ())
-- done = 0, update_insns (), update_insn_infos ();
-+ done = 0, update_insns ();
-
- if (do_elim_dead_assign && opt_elim_dead_assign ())
-- done = 0, update_insns (), update_insn_infos ();
-+ done = 0, update_insns ();
-
- if (do_bb_reg_rename)
- {
- while (opt_reg_rename ())
- {
- update_insns ();
-- update_insn_infos ();
- done = 0;
- }
- }
-@@ -2308,7 +2513,6 @@ namespace
- {
- opt_shrink_stack_frame ();
- update_insns ();
-- update_insn_infos ();
- }
-
- if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
-
-From c7349bb3c9644ea0ceb0f82b8e739df734db9317 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 28 Apr 2017 13:32:51 +0200
-Subject: [PATCH 100/303] @R optimize opt_merge_add - no need to run
- update_insns afterwards
-
----
- gcc/bbb-opts.c | 108 ++++++++++++++++++++++++++++++++++++++++++++-------------
- 1 file changed, 84 insertions(+), 24 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 99c41128e5b8..9d40a534dc1a 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -154,9 +154,6 @@ class insn_info
- int src_mem_regno;
- unsigned src_intval;
-
-- insn_info &
-- operator = (insn_info const &);
--
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
-@@ -166,14 +163,14 @@ class insn_info
- {
- }
-
-- inline void
-- plus_to_move (rtx_insn * newinsn)
-- {
-- insn = newinsn;
-- dst_plus = false;
-- dst_reg = true;
-- // usage flags did not change
-- }
-+ int
-+ get_index () const;
++/* begin-GG-local: explicit register specification for parameters */
+
-+ void
-+ plus_to_move (rtx_insn * newinsn);
++/* Note: this is an extension of m68k_args */
+
-+ void
-+ swap_adds(rtx_insn * newinsn, insn_info & ii);
-
- inline bool
- is_dst_reg () const
-@@ -715,7 +712,69 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- */
- static std::vector<insn_info> infos;
- static std::vector<rtx_insn *> jumps;
--static std::map<rtx_insn *, unsigned> insn2index;
-+static std::map<rtx_insn *, insn_info *> insn2index;
+
-+static insn_info * info0;
++#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))
+
-+static void
-+update_insn2index ()
-+{
-+ infos.reserve (infos.size () * 8 / 7 + 2);
-+ insn2index.clear ();
-+ /* needs a separate pass since the insn_infos require fixed addresses for ->get_index() */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ insn2index.insert (std::make_pair (ii.get_insn (), &ii));
-+ }
-+ info0 = &infos[0];
-+}
+
-+int
-+insn_info::get_index () const
-+{
-+ insn_info * ii = &infos[0];
++/*
++ 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.
++*/
+
-+ if (ii == info0)
-+ {
-+ ptrdiff_t diff = ((char const *) this - (char const *) ii);
-+ unsigned pos = diff / sizeof(insn_info);
-+ if (pos < infos.size ())
-+ return pos;
-+ }
++extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *cum, tree);
++extern void amigaos_function_arg_advance (cumulative_args_t, machine_mode, const_tree, bool);
++extern rtx amigaos_function_arg (cumulative_args_t, machine_mode, const_tree, bool);
++extern cumulative_args_t amigaos_pack_cumulative_args (CUMULATIVE_ARGS *);
++extern int amigaos_comp_type_attributes (const_tree, const_tree);
++extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
+
-+ // realloc happened...
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ if (infos[i].get_insn () == this->insn)
-+ return i;
++/* 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.) */
+
-+ // whoops!?
-+ return 0;
-+}
++#undef TARGET_FUNCTION_ARG_ADVANCE
++#define TARGET_FUNCTION_ARG_ADVANCE amigaos_function_arg_advance
+
-+void
-+insn_info::plus_to_move (rtx_insn * newinsn)
-+{
-+ insn = newinsn;
-+ src_plus = false;
-+ src_reg = true;
-+ insn2index.insert(std::make_pair(insn, this));
-+ // usage flags did not change
-+}
++/* A C expression that controls whether a function argument is passed
++ in a register, and which register. */
+
-+void
-+insn_info::swap_adds(rtx_insn * newinsn, insn_info & ii)
-+{
-+ insn = newinsn;
++#undef TARGET_FUNCTION_ARG
++#define TARGET_FUNCTION_ARG amigaos_function_arg
+
-+ std::swap(*this, ii);
++#undef TARGET_PACK_CUMULATIVE_ARGS
++#define TARGET_PACK_CUMULATIVE_ARGS(CUM) \
++ (amigaos_pack_cumulative_args(&(CUM)))
+
-+ insn2index.insert(std::make_pair(insn, this));
-+ insn2index.insert(std::make_pair(ii.insn, &ii));
++#undef TARGET_COMP_TYPE_ATTRIBUTES
++#define TARGET_COMP_TYPE_ATTRIBUTES amigaos_comp_type_attributes
+
-+ // usage flags did not change
-+}
+
-
- /*
- * Reset collected data.
-@@ -759,7 +818,7 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- if (i == insn2index.end ())
- return;
-
-- insn_info & ii = infos[i->second];
-+ insn_info & ii = *i->second;
-
- if (f != stderr)
- fprintf (f, "\n\t\t\t\t\t\t| ");
-@@ -867,9 +926,9 @@ update_insn_infos (void)
- {
- if (JUMP_LABEL(*i) == insn)
- {
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find (*i);
-+ auto j = insn2index.find (*i);
- if (j != insn2index.end ())
-- todo.push_back (std::make_pair (j->second, ii));
-+ todo.push_back (std::make_pair (j->second->get_index (), ii));
- }
- }
- continue;
-@@ -935,7 +994,6 @@ update_insns ()
- if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
- {
-
-- insn2index.insert (std::make_pair (insn, infos.size ()));
- infos.push_back (insn_info (insn, inproepilogue));
- insn_info & ii = infos[infos.size () - 1];
-
-@@ -970,6 +1028,8 @@ update_insns ()
- inproepilogue = 2;
- }
- }
++/* end-GG-local */
+
-+ update_insn2index ();
- update_insn_infos ();
- }
-
-@@ -1088,11 +1148,11 @@ opt_reg_rename (void)
- {
- if (JUMP_LABEL(*i) == insn)
- {
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find (*i);
-+ auto j = insn2index.find (*i);
- if (j == insn2index.end ())
- continue;
-
-- unsigned start = j->second;
-+ unsigned start = j->second->get_index ();
- if (!infos[start].is_use (rename_regno))
- continue;
-
-@@ -1131,7 +1191,7 @@ opt_reg_rename (void)
- /* follow jump and/or next insn. */
- if (JUMP_P(insn))
- {
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-+ auto j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
- if (j == insn2index.end ())
- {
- /* whoops - label not found. */
-@@ -1139,7 +1199,7 @@ opt_reg_rename (void)
- break;
- }
-
-- unsigned label_index = j->second;
-+ unsigned label_index = j->second->get_index ();
- if (found.find (label_index) == found.end ())
- {
- /* if the rename_reg is used in the insn before.
-@@ -1827,9 +1887,9 @@ opt_const_cmp_to_sub (void)
- if (!JUMP_P(patchme))
- continue;
-
-- std::map<rtx_insn *, unsigned>::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(patchme));
-+ auto j = insn2index.find ((rtx_insn *) JUMP_LABEL(patchme));
- if (j != insn2index.end ())
-- todo.push_back (j->second);
-+ todo.push_back (j->second->get_index ());
-
- rtx jmppattern = PATTERN (patchme);
-
-@@ -1971,7 +2031,7 @@ opt_merge_add (void)
- rtx_insn * newins1 = make_insn_raw (PATTERN (insn1));
- add_insn_after (newins1, insn2, 0);
- SET_INSN_DELETED(insn1);
--// ii1.swap_adds(newins1, ii2);
-+ ii1.swap_adds(newins1, ii2);
-
- ++change_count;
- }
-@@ -2491,7 +2551,7 @@ namespace
- done = 0, update_insns ();
-
- if (do_merge_add && opt_merge_add ())
-- done = 0, update_insns ();
-+ done = 0;
-
- if (do_elim_dead_assign && opt_elim_dead_assign ())
- done = 0, update_insns ();
-
-From 6bfa56b92ce1a9b99b72ef18b7ba14d71542ef8e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 28 Apr 2017 17:45:15 +0200
-Subject: [PATCH 101/303] @N add opt_immediate
-
----
- gcc/bbb-opts.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
- 1 file changed, 163 insertions(+), 11 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 9d40a534dc1a..aa841f737cf8 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -170,7 +170,10 @@ class insn_info
- plus_to_move (rtx_insn * newinsn);
-
- void
-- swap_adds(rtx_insn * newinsn, insn_info & ii);
-+ swap_adds (rtx_insn * newinsn, insn_info & ii);
++#undef SUBTARGET_OVERRIDE_OPTIONS
++#define SUBTARGET_OVERRIDE_OPTIONS \
++do \
++ { \
++ if (flag_resident) \
++ { \
++ if (flag_pic) \
++ error ("-fbaserel and -resident are mutual exclusiv\n"); \
++ flag_pic = flag_resident; \
++ } \
++ if (!TARGET_68020 && flag_pic==4) \
++ error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \
++ if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
++ error ("-mregparm=x with 1 <= x <= %d\n", AMIGAOS_MAX_REGPARM); \
++ } \
++while (0)
+
-+ void
-+ immediate2base (unsigned regno, unsigned base);
-
- inline bool
- is_dst_reg () const
-@@ -178,6 +181,48 @@ class insn_info
- return dst_reg;
- }
-
-+ inline bool
-+ is_dst_mem () const
-+ {
-+ return dst_mem;
-+ }
++/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
++ affects_type_identity } */
++#define SUBTARGET_ATTRIBUTES \
++ { "asmregs", 0, 0, false, false, false, 0, true }, \
++ { "chip", 0, 0, false, true, false, amigaos_handle_type_attribute, false }, \
++ { "fast", 0, 0, false, true, false, amigaos_handle_type_attribute, false }, \
++ { "far", 0, 0, false, true, false, amigaos_handle_type_attribute, false }, \
++ { "saveds", 0, 0, false, true, true, amigaos_handle_type_attribute, false }, \
++ { "regparm", 1, 1, false, true, true, amigaos_handle_type_attribute,\
++ true }, \
++ { "stkparm", 0, 0, false, true, true, amigaos_handle_type_attribute,\
++ true },
+
-+ inline bool
-+ has_dst_memreg () const
-+ {
-+ return dst_mem_reg >= 0;
-+ }
++#define GOT_SYMBOL_NAME ""
+
-+ inline bool
-+ has_dst_addr () const
-+ {
-+ return dst_mem_addr != 0;
-+ }
++#undef TARGET_RTX_COSTS
++#define TARGET_RTX_COSTS amigaos_rtx_costs
++bool
++amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+
-+ inline bool
-+ is_label () const
-+ {
-+ return label;
-+ }
++#undef TARGET_STRUCT_VALUE_RTX
++#define TARGET_STRUCT_VALUE_RTX amigaos_struct_value_rtx
++rtx
++amigaos_struct_value_rtx(tree fntype,
++ int incoming ATTRIBUTE_UNUSED);
+
-+ inline bool
-+ is_jump () const
-+ {
-+ return jump;
-+ }
++#undef TARGET_STATIC_CHAIN
++#define TARGET_STATIC_CHAIN amigaos_static_chain_rtx
++rtx
++amigaos_static_chain_rtx(const_tree fntype,
++ bool incoming ATTRIBUTE_UNUSED);
+
-+ inline bool
-+ is_call () const
-+ {
-+ return call;
-+ }
+
-+ inline unsigned
-+ get_dst_addr () const
-+ {
-+ return dst_mem_addr;
-+ }
++extern bool
++amigaos_legitimate_src (rtx src);
+
- inline bool
- is_src_reg () const
- {
-@@ -447,7 +492,7 @@ class insn_info
- if (def & hard)
- return 0;
-
-- if (!def || def > 0x1000)
-+ if (!def || (def & ~(1 << FIRST_PSEUDO_REGISTER)) > 0x1000)
- return 0;
-
- unsigned mask = def - 1;
-@@ -758,24 +803,53 @@ insn_info::plus_to_move (rtx_insn * newinsn)
- insn = newinsn;
- src_plus = false;
- src_reg = true;
-- insn2index.insert(std::make_pair(insn, this));
-+ insn2index.insert (std::make_pair (insn, this));
- // usage flags did not change
- }
-
- void
--insn_info::swap_adds(rtx_insn * newinsn, insn_info & ii)
-+insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
- {
- insn = newinsn;
-
-- std::swap(*this, ii);
-+ std::swap (*this, ii);
-
-- insn2index.insert(std::make_pair(insn, this));
-- insn2index.insert(std::make_pair(ii.insn, &ii));
-+ insn2index.insert (std::make_pair (insn, this));
-+ insn2index.insert (std::make_pair (ii.insn, &ii));
-
- // usage flags did not change
- }
-
-+void
-+insn_info::immediate2base (unsigned regno, unsigned base)
-+{
-+ rtx set = PATTERN (get_insn ());
-+ rtx src = SET_SRC(set);
-+ machine_mode mode = GET_MODE(SET_DEST(set));
++extern void
++amigaos_restore_a4 (void);
+
-+ unsigned addr = get_dst_addr ();
-+ unsigned offset = addr - base;
++extern void
++amigaos_alternate_frame_setup_f (int fsize);
+
-+ rtx pattern;
-+ if (base == addr)
-+ pattern = gen_rtx_SET(gen_rtx_MEM (mode, gen_raw_REG (SImode, regno)), SET_SRC(set));
-+ else
-+ pattern = gen_rtx_SET(
-+ gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, gen_raw_REG (SImode, regno), gen_rtx_CONST_INT(SImode, offset))),
-+ SET_SRC(set));
++extern void
++amigaos_alternate_frame_setup (int fsize);
+
-+ SET_INSN_DELETED(insn);
-+ insn = emit_insn_after (pattern, insn);
+
-+ mark_use (regno);
++#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND
+
-+ dst_mem_reg = regno;
-+ dst_mem = true;
-+ dst_mem_addr = offset;
-+ dst_plus = offset != 0;
-
-+ insn2index.insert (std::make_pair (insn, this));
-+}
- /*
- * Reset collected data.
- */
-@@ -1987,19 +2061,19 @@ opt_merge_add (void)
- insn_info & ii1 = infos[index + 1];
- insn_info & ii2 = infos[index + 2];
-
-- if (!ii2.is_dst_reg ())
-+ if (!ii2.is_dst_reg () || ii2.is_dst_mem ())
- {
- index += 2;
- continue;
- }
-
-- if (!ii1.is_dst_reg ())
-+ if (!ii1.is_dst_reg () || ii1.is_dst_mem ())
- {
- ++index;
- continue;
- }
-
-- if (!ii0.is_dst_reg () || !ii0.is_src_plus () || !ii1.is_src_plus () || !ii2.is_src_plus ())
-+ if (ii0.is_dst_mem () || !ii0.is_dst_reg () || !ii0.is_src_plus () || !ii1.is_src_plus () || !ii2.is_src_plus ())
- continue;
-
- if (!ii0.is_src_const () || !ii1.is_src_reg () || !ii2.is_src_const ())
-@@ -2031,7 +2105,7 @@ opt_merge_add (void)
- rtx_insn * newins1 = make_insn_raw (PATTERN (insn1));
- add_insn_after (newins1, insn2, 0);
- SET_INSN_DELETED(insn1);
-- ii1.swap_adds(newins1, ii2);
-+ ii1.swap_adds (newins1, ii2);
-
- ++change_count;
- }
-@@ -2464,6 +2538,80 @@ opt_shrink_stack_frame (void)
- return 0;
- }
-
-+static unsigned
-+opt_immediate (void)
-+{
-+ unsigned change_count = 0;
++#define ALTERNATE_FRAME_SETUP_F(FSIZE) \
++ (amigaos_alternate_frame_setup_f ((FSIZE)))
+
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (!ii.is_dst_mem () || !ii.has_dst_addr () || ii.has_dst_memreg())
-+ continue;
++#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND
+
-+ unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00;
-+ if (!freemask)
-+ continue;
++#define ALTERNATE_FRAME_SETUP(FSIZE) \
++ (amigaos_alternate_frame_setup ((FSIZE)))
+
-+ std::vector<unsigned> found;
-+ found.push_back (i);
-+ unsigned base = ii.get_dst_addr ();
-+ unsigned j = i + 1;
-+ for (; j < infos.size (); ++j)
-+ {
-+ insn_info & jj = infos[j];
-+ if (jj.is_label () || jj.is_jump () || jj.is_call ())
-+ break;
++#undef TARGET_INSERT_ATTRIBUTES
++#define TARGET_INSERT_ATTRIBUTES amiga_insert_attribute
+
-+ freemask &= ~(jj.get_use () | jj.get_def ());
-+ if (!freemask)
-+ break;
++void
++amiga_insert_attribute (tree decl, tree * attr);
+diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
+new file mode 100644
+index 000000000000..07406d27a777
+--- /dev/null
++++ gcc/config/m68k/amigaos.opt
+@@ -0,0 +1,63 @@
+
-+ if (jj.is_dst_mem () && jj.has_dst_addr () && !jj.has_dst_memreg())
-+ {
-+ unsigned addr = jj.get_dst_addr ();
-+ if (addr < base)
-+ base = addr;
-+ if (addr - base > 0x7ffc)
-+ continue;
++mregparm=
++Target RejectNegative Var(amigaos_regparm) Joined UInteger Init(-1)
++Pass arguments through registers.
+
-+ found.push_back (j);
-+ }
-+ }
++noixemul
++Target RejectNegative
++Do not use ixemul.library - use libnix instead to link
+
-+ if (freemask && found.size () > 2)
-+ {
-+ unsigned regno = bit2regno (freemask);
-+ log ("modifying %d immediate using %s\n", found.size (), reg_names[regno]);
++ramiga-lib
++Target RejectNegative
++Use libinit.o as start file
+
-+ for (auto k = found.begin (); k != found.end (); ++k)
-+ {
-+ insn_info & kk = infos[*k];
-+ kk.immediate2base (regno, base);
-+ }
++ramiga-libr
++Target RejectNegative
++Use libinitr.o as start file
+
-+ // load base into reg
-+ rtx lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
-+ rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
-+ insn_info nn (insn);
-+ nn.scan();
-+ nn.fledder (lea);
-+ nn.mark_def (regno);
-+ infos.insert (infos.begin () + i, nn);
-+ while (i++ < j)
-+ infos[i].mark_use(regno);
-+ ++j;
-+ }
++ramiga-dev
++Target RejectNegative
++Use devinit.o as start file
+
-+ i = j;
-+ }
++msmall-code
++Target RejectNegative Var(flag_smallcode,1)
++small code model
+
-+ if (change_count)
-+ update_insn2index ();
++fbaserel
++Target Report Var(flag_pic,3)
++data is addressed relative to a4
+
-+ return change_count;
-+}
++fbaserel32
++Target Report Var(flag_pic,4)
++data is addressed relative to a4 with 32 bit offsets
+
- namespace
- {
-
-@@ -2533,6 +2681,7 @@ namespace
- bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr (string_bbb_opts, '+');
- bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
- bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
-+ bool do_immediate = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
-
- for (;;)
- {
-@@ -2556,6 +2705,9 @@ namespace
- if (do_elim_dead_assign && opt_elim_dead_assign ())
- done = 0, update_insns ();
-
-+ if (do_immediate && opt_immediate ())
-+ done = 0, update_insns ();
-+
- if (do_bb_reg_rename)
- {
- while (opt_reg_rename ())
-
-From d851a82657b37cc2fd5f8077fd97c9ea8bef0bfc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 28 Apr 2017 18:21:19 +0200
-Subject: [PATCH 102/303] @B fix opt_merge_add
-
----
- gcc/bbb-opts.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index aa841f737cf8..face11f85f8a 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -187,6 +187,12 @@ class insn_info
- return dst_mem;
- }
-
-+ inline bool
-+ is_src_mem () const
-+ {
-+ return src_mem;
-+ }
++resident
++Target Common Report Var(flag_resident,3)
++data is addressed relative to a4, linked as resident
+
- inline bool
- has_dst_memreg () const
- {
-@@ -2073,10 +2079,10 @@ opt_merge_add (void)
- continue;
- }
-
-- if (ii0.is_dst_mem () || !ii0.is_dst_reg () || !ii0.is_src_plus () || !ii1.is_src_plus () || !ii2.is_src_plus ())
-+ if (!ii0.is_dst_reg () || !ii0.is_src_plus () || !ii1.is_src_plus () || !ii2.is_src_plus ())
- continue;
-
-- if (!ii0.is_src_const () || !ii1.is_src_reg () || !ii2.is_src_const ())
-+ if (ii0.is_src_mem () || !ii0.is_src_const () || !ii1.is_src_reg () || ii2.is_src_mem () || !ii2.is_src_const ())
- continue;
-
- if (ii0.get_dst_regno () != ii1.get_dst_regno () || ii1.get_src_regno () != ii2.get_dst_regno ())
-
-From 25996bade9f5e8d41f81fac1d07cb82cebe5832c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 28 Apr 2017 21:55:59 +0200
-Subject: [PATCH 103/303] @B fix opt_immediate: update reg usage
-
----
- gcc/bbb-opts.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index face11f85f8a..5683ac21640b 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -358,6 +358,13 @@ class insn_info
- {
- return use;
- }
++resident32
++Target Common Report Var(flag_resident,4)
++data is addressed relative to a4 with 32 bit offsets, linked as resident
+
-+ inline void
-+ set_use(unsigned u)
-+ {
-+ use = u;
-+ }
++mcrt=
++Target RejectNegative Var(amigaos_crt) Joined
++Specify startup binary
+
- inline unsigned
- get_def () const
- {
-@@ -1288,7 +1295,7 @@ opt_reg_rename (void)
- insn_info & bb = infos[label_index + 1];
- if (bb.is_use (rename_regno))
- {
-- unsigned start = find_start (found, label_index - 1, rename_regno);
-+ unsigned start = find_start (found, label_index, rename_regno);
- todo.push_back (start);
- }
- todo.push_back (label_index + 1);
-@@ -2600,6 +2607,7 @@ opt_immediate (void)
- rtx lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
- rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
- insn_info nn (insn);
-+ nn.set_use(ii.get_use());
- nn.scan();
- nn.fledder (lea);
- nn.mark_def (regno);
-
-From 3fdf716d76ad01cdef87f14ebceb8832ca9b32a7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 28 Apr 2017 23:07:13 +0200
-Subject: [PATCH 104/303] @B fix opt_immediate: update reg usage
-
----
- gcc/bbb-opts.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 5683ac21640b..99c49db4238d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2615,6 +2615,7 @@ opt_immediate (void)
- while (i++ < j)
- infos[i].mark_use(regno);
- ++j;
-+ ++change_count;
- }
-
- i = j;
-
-From b68846bfd5192be42bf080d09e429227aebdb7d3 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 30 Apr 2017 18:27:54 +0200
-Subject: [PATCH 105/303] @I cleanup, remove unnecessary changes
-
----
- .cproject | 6 +++++-
- gcc/DATESTAMP | 2 +-
- gcc/cfgbuild.c | 1 -
- gcc/config/m68k/amigaos.c | 10 ----------
- gcc/config/m68k/amigaos.h | 4 ----
- gcc/doc/tm.texi | 4 ----
- gcc/doc/tm.texi.in | 2 --
- gcc/final.c | 7 +------
- gcc/regrename.c | 5 ++---
- gcc/target.def | 19 -------------------
- gcc/targhooks.c | 7 -------
- gcc/targhooks.h | 1 -
- gcc/toplev.c | 2 +-
- 13 files changed, 10 insertions(+), 60 deletions(-)
-
-diff --git a/.cproject b/.cproject
-index 62b1c0f38dcb..b3cddaefb27b 100755
---- .cproject
-+++ .cproject
-@@ -42,6 +42,7 @@
- <option id="gnu.cpp.compiler.option.preprocessor.def.807277038" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin"/>
- </tool>
-@@ -56,12 +57,13 @@
- <option id="gnu.c.compiler.option.preprocessor.def.symbols.1982594045" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313" superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
- </tool>
- <tool id="cdt.managedbuild.tool.gnu.c.linker.cygwin.base.344641511" name="Cygwin C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.cygwin.base"/>
- <tool id="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base.968200320" name="Cygwin C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base">
-- <option id="gnu.cpp.link.option.libs.260033787" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"/>
-+ <option id="gnu.cpp.link.option.libs.260033787" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs"/>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1537937183" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
- <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
- <additionalInput kind="additionalinput" paths="$(LIBS)"/>
-@@ -103,6 +105,7 @@
- <option id="gnu.c.compiler.option.preprocessor.def.symbols.652362073" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1150724656" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
- </tool>
-@@ -115,6 +118,7 @@
- <option id="gnu.cpp.compiler.option.preprocessor.def.625117841" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
- </tool>
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index efbcba2793ea..59aff9a1ff47 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170426
-+20170430
-diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
-index 1f488dc54544..c1ec46ad8d7f 100644
---- gcc/cfgbuild.c
-+++ gcc/cfgbuild.c
-@@ -55,7 +55,6 @@ inside_basic_block_p (const rtx_insn *insn)
- case DEBUG_INSN:
- return true;
-
-- case DEBUG_IMPLICIT_PTR:
- case JUMP_TABLE_DATA:
- case BARRIER:
- case NOTE:
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 27831df2d543..419d59dc3871 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -839,13 +839,3 @@ read_only_operand (rtx operand)
- return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P(operand);
- return 1;
- }
--
--reg_class_t
--amiga_preferred_rename_class2 (reg_class_t rclass ATTRIBUTE_UNUSED, int regno)
--{
-- if (regno == 0)
-- return D0_REGS;
-- if (regno == 8)
-- return A0_REGS;
-- return regno_reg_class[regno];
--}
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 49dd90d745c3..e2a2b4cc11f6 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -486,7 +486,3 @@ amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
- && GET_CODE(XEXP(XEXP(XEXP(x, 0), 1), 0)) == UNSPEC \
- )
-
--#undef TARGET_PREFERRED_RENAME_CLASS2
--#define TARGET_PREFERRED_RENAME_CLASS2 amiga_preferred_rename_class2
--reg_class_t
--amiga_preferred_rename_class2(reg_class_t, int);
-diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
-index 6604514427fa..745910f9a331 100644
---- gcc/doc/tm.texi
-+++ gcc/doc/tm.texi
-@@ -2489,10 +2489,6 @@ only if neither labeling works.
- A target hook that places additional preference on the register class to use when it is necessary to rename a register in class @var{rclass} to another class, or perhaps @var{NO_REGS}, if no preferred register class is found or hook @code{preferred_rename_class} is not implemented. Sometimes returning a more restrictive class makes better code. For example, on ARM, thumb-2 instructions using @code{LO_REGS} may be smaller than instructions using @code{GENERIC_REGS}. By returning @code{LO_REGS} from @code{preferred_rename_class}, code size can be reduced.
- @end deftypefn
-
--@deftypefn {Target Hook} reg_class_t TARGET_PREFERRED_RENAME_CLASS2 (reg_class_t @var{rclass}, int @var{regno})
--A target hook that places additional preference on the register class to use when it is necessary to rename a register in class @var{rclass} to another class, or perhaps @var{NO_REGS}, if no preferred register class is found or hook @code{preferred_rename_class2} is not implemented. Sometimes returning a more restrictive class makes better code. For example, on ARM, thumb-2 instructions using @code{LO_REGS} may be smaller than instructions using @code{GENERIC_REGS}. By returning @code{LO_REGS} from @code{preferred_rename_class2}, code size can be reduced.
--@end deftypefn
--
- @deftypefn {Target Hook} reg_class_t TARGET_PREFERRED_RELOAD_CLASS (rtx @var{x}, reg_class_t @var{rclass})
- A target hook that places additional restrictions on the register class
- to use when it is necessary to copy value @var{x} into a register in class
-diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
-index e4da2a94249b..f31c763991c5 100644
---- gcc/doc/tm.texi.in
-+++ gcc/doc/tm.texi.in
-@@ -2281,8 +2281,6 @@ only if neither labeling works.
-
- @hook TARGET_PREFERRED_RENAME_CLASS
-
--@hook TARGET_PREFERRED_RENAME_CLASS2
--
- @hook TARGET_PREFERRED_RELOAD_CLASS
-
- @defmac PREFERRED_RELOAD_CLASS (@var{x}, @var{class})
-diff --git a/gcc/final.c b/gcc/final.c
-index 31f9b4815d75..55cf509611f7 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -2165,7 +2165,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
-
- /* Ignore deleted insns. These can occur when we split insns (due to a
- template of "#") while not optimizing. */
-- if (insn->deleted () || GET_CODE(insn) == VALUE || GET_CODE(insn) == CONST_FIXED || GET_CODE(insn) == DEBUG_IMPLICIT_PTR)
-+ if (insn->deleted ())
- return NEXT_INSN (insn);
-
- switch (GET_CODE (insn))
-@@ -4430,17 +4430,12 @@ leaf_renumber_regs_insn (rtx in_rtx)
- }
- #endif
-
--
--extern void dump_insns(char const *);
--
- /* Turn the RTL into assembly. */
- static unsigned int
- rest_of_handle_final (void)
- {
- const char *fnname = get_fnname_from_decl (current_function_decl);
-
--// dump_insns("final");
--
- assemble_start_function (current_function_decl, fnname);
- final_start_function (get_insns (), asm_out_file, optimize);
- final (get_insns (), asm_out_file, optimize);
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index 1ed6557ee713..b3818a80846d 100755
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -406,9 +406,8 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
-
- /* In the first pass, we force the renaming of registers that
- don't belong to PREFERRED_CLASS to registers that do, even
-- though the latters were used not very long ago.
-- Also use a register if no best_new_reg was found till now */
-- if (((pass == 0 || !has_preferred_class)
-+ though the latters were used not very long ago. */
-+ if ((pass == 0
- && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
- best_new_reg))
- || tick[best_new_reg] > tick[new_reg])
-diff --git a/gcc/target.def b/gcc/target.def
-index d0208812d83b..20f2b32da1e9 100644
---- gcc/target.def
-+++ gcc/target.def
-@@ -5170,25 +5170,6 @@ DEFHOOK
- reg_class_t, (reg_class_t rclass),
- default_preferred_rename_class)
-
--/*A target hook that places additional preference on the register
-- class
-- */
--DEFHOOK
--(preferred_rename_class2,
-- "A target hook that places additional preference on the register\
-- class to use when it is necessary to rename a register in class\
-- @var{rclass} to another class, or perhaps @var{NO_REGS}, if no\
-- preferred register class is found or hook @code{preferred_rename_class2}\
-- is not implemented.\
-- Sometimes returning a more restrictive class makes better code. For\
-- example, on ARM, thumb-2 instructions using @code{LO_REGS} may be\
-- smaller than instructions using @code{GENERIC_REGS}. By returning\
-- @code{LO_REGS} from @code{preferred_rename_class2}, code size can\
-- be reduced.",
-- reg_class_t, (reg_class_t rclass, int regno),
-- default_preferred_rename_class2)
--
--
- /* This target hook allows the backend to avoid unsafe substitution
- during register allocation. */
- DEFHOOK
-diff --git a/gcc/targhooks.c b/gcc/targhooks.c
-index e106af7b261d..a34227705d2b 100644
---- gcc/targhooks.c
-+++ gcc/targhooks.c
-@@ -1542,13 +1542,6 @@ default_preferred_rename_class (reg_class_t rclass ATTRIBUTE_UNUSED)
- return NO_REGS;
- }
-
--/* The default implementation of TARGET_PREFERRED_RENAME_CLASS2. */
--reg_class_t
--default_preferred_rename_class2 (reg_class_t rclass, int regno ATTRIBUTE_UNUSED)
--{
-- return targetm.preferred_rename_class(rclass);
--}
--
- /* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P. */
-
- bool
-diff --git a/gcc/targhooks.h b/gcc/targhooks.h
-index 0a21ef982a65..7687c39b53b5 100644
---- gcc/targhooks.h
-+++ gcc/targhooks.h
-@@ -204,7 +204,6 @@ extern bool default_profile_before_prologue (void);
- extern reg_class_t default_preferred_reload_class (rtx, reg_class_t);
- extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t);
- extern reg_class_t default_preferred_rename_class (reg_class_t rclass);
--extern reg_class_t default_preferred_rename_class2 (reg_class_t rclass, int regno);
- extern bool default_class_likely_spilled_p (reg_class_t);
- extern unsigned char default_class_max_nregs (reg_class_t, machine_mode);
-
-diff --git a/gcc/toplev.c b/gcc/toplev.c
-index 83800763f30d..59604e56195b 100644
---- gcc/toplev.c
-+++ gcc/toplev.c
-@@ -1324,7 +1324,7 @@ process_options (void)
- flag_web = flag_unroll_loops || flag_peel_loops;
-
- if (flag_rename_registers == AUTODETECT_VALUE)
-- flag_rename_registers = flag_unroll_loops || flag_peel_loops || optimize >= 2;
-+ flag_rename_registers = flag_unroll_loops || flag_peel_loops;
-
- if (flag_non_call_exceptions)
- flag_asynchronous_unwind_tables = 1;
-
-From beb1cfb6a364fbe542b38cc4a4206219b465a671 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 2 May 2017 22:42:17 +0200
-Subject: [PATCH 106/303] @B fix stack frame shrink/removal with frame pointer,
- @I some internal changes
-
----
- gcc/bbb-opts.c | 236 +++++++++++++++++++++++++++++++++++---------------------
- gcc/regrename.c | 5 +-
- 2 files changed, 153 insertions(+), 88 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 99c49db4238d..6a27fcf72544 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -75,7 +75,12 @@ bool be_very_verbose;
- bool be_verbose;
-
- #ifdef __ECLIPSE__
--extern char * string_bbb_opts;
-+//extern char * string_bbb_opts;
-+#define FIRST_PSEUDO_REGISTER 25
-+#define FRAME_POINTER_REGNUM 13
-+#define STACK_POINTER_REGNUM 15
-+#define NOTICE_UPDATE_CC(a,b)
-+#define Pmode SImode
- #endif
- extern struct lang_hooks lang_hooks;
-
-@@ -138,28 +143,25 @@ class insn_info
- bool jump;
- bool call;
- bool compare;
-- bool dst_reg;
-- bool src_reg;
- bool dst_mem;
- bool src_mem;
- bool dst_plus;
- bool src_plus;
- bool src_const;
-
-- int dst_regno;
-- int dst_mem_reg;
-+ rtx dst_reg;
-+ rtx dst_mem_reg;
-+ rtx src_reg;
-+ rtx src_mem_reg;
- unsigned dst_mem_addr;
-
-- int src_regno;
-- int src_mem_regno;
- unsigned src_intval;
-
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
-- false), compare (false), dst_reg (false), src_reg (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (
-- false), src_const (false), dst_regno (-1), dst_mem_reg (-1), dst_mem_addr (0), src_regno (-1), src_mem_regno (
-- -1), src_intval (0)
-+ false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_const (
-+ false), dst_reg (0), dst_mem_reg (0), src_reg (0), src_mem_reg (0), dst_mem_addr (0), src_intval (0)
- {
- }
-
-@@ -173,7 +175,7 @@ class insn_info
- swap_adds (rtx_insn * newinsn, insn_info & ii);
-
- void
-- immediate2base (unsigned regno, unsigned base);
-+ absolute2base (unsigned regno, unsigned base);
-
- inline bool
- is_dst_reg () const
-@@ -196,13 +198,13 @@ class insn_info
- inline bool
- has_dst_memreg () const
- {
-- return dst_mem_reg >= 0;
-+ return dst_mem_reg;
- }
++fbbb=
++Target RejectNegative Report Var(string_bbb_opts) Joined
++-fbbb=Enable Bebbo's optimizations.
+++ enable all optimizations
++a commute add move instructions
++b use register for base addresses
++c convert load const and compare into a sub
++e eliminate dead assignments + redundant loads
++f shrink stack frame
++i use post increment on addresses
++m merge add and move statements
++p propagate move assignment pairs out of loops
++r register renaming to maybe save registers
++s a strcpy optimization
++v be verbose
++V be very verbose
++x dump insns
++Default: -fbbb=+ which yields -fbbb=abcefimprs
+diff --git a/gcc/config/m68k/constraints.md b/gcc/config/m68k/constraints.md
+index b62120895304..1223852570c1 100644
+--- gcc/config/m68k/constraints.md
++++ gcc/config/m68k/constraints.md
+@@ -1,5 +1,5 @@
+ ;; Constraint definitions for m68k
+-;; Copyright (C) 2007-2016 Free Software Foundation, Inc.
++;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
- inline bool
- has_dst_addr () const
- {
-- return dst_mem_addr != 0;
-+ return dst_mem_addr;
- }
+ ;; This file is part of GCC.
- inline bool
-@@ -232,25 +234,55 @@ class insn_info
- inline bool
- is_src_reg () const
- {
-- return src_reg;
-+ return src_reg && !src_plus;
-+ }
+diff --git a/gcc/config/m68k/host-amigaos.c b/gcc/config/m68k/host-amigaos.c
+new file mode 100755
+index 000000000000..8c72d516a378
+--- /dev/null
++++ gcc/config/m68k/host-amigaos.c
+@@ -0,0 +1,42 @@
++/* AmigaOS/m68k host-specific hook definitions.
++ Copyright (C) 2003 Free Software Foundation, Inc.
+
-+ inline bool
-+ is_src_plus () const
-+ {
-+ return src_reg && src_plus;
-+ }
++This file is part of GCC.
+
-+ inline bool
-+ is_src_mem_plus () const
-+ {
-+ return src_mem && src_plus;
- }
-
- inline int
- get_dst_regno () const
- {
-- return dst_regno;
-+ return dst_reg ? REGNO(dst_reg) : -1;
- }
-
- inline int
- get_src_regno () const
- {
-- return src_regno;
-+ return src_reg ? REGNO(src_reg) : -1;
- }
-
-- inline bool
-- is_src_plus () const
-+ inline rtx
-+ get_src_reg () const
-+ {
-+ return src_reg;
-+ }
++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.
+
-+ inline rtx
-+ get_dst_reg () const
-+ {
-+ return dst_reg;
-+ }
++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.
+
-+ inline int
-+ get_src_mem_regno () const
-+ {
-+ return src_mem_reg ? REGNO(src_mem_reg) : -1;
-+ }
++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. */
+
-+ inline int
-+ get_src_intval () const
- {
-- return src_plus;
-+ return src_intval;
- }
-
- inline bool
-@@ -360,7 +392,7 @@ class insn_info
- }
-
- inline void
-- set_use(unsigned u)
-+ set_use (unsigned u)
- {
- use = u;
- }
-@@ -431,6 +463,13 @@ class insn_info
- return *this;
- }
-
-+ inline insn_info &
-+ or_use (insn_info const & o)
-+ {
-+ use |= o.myuse | o.def | o.hard;
-+ return *this;
-+ }
+
- inline insn_info &
- drop_def ()
- {
-@@ -524,6 +563,10 @@ class insn_info
- {
- return def & ~hard & ~use & 0x7fff;
- }
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "hosthooks.h"
++#include "hosthooks-def.h"
++#include "toplev.h"
+
-+ void
-+ set_insn (rtx_insn * newinsn);
++static void * amigaos_m68k_gt_pch_get_address (size_t);
+
- };
-
- void
-@@ -634,15 +677,14 @@ insn_info::fledder (rtx set)
-
- if (REG_P(dst))
- {
-- dst_reg = true;
-- dst_regno = REGNO(dst);
-+ dst_reg = dst;
- }
- else if (MEM_P(dst))
- {
- dst_mem = true;
- rtx mem = XEXP(dst, 0);
- if (REG_P(mem))
-- dst_mem_reg = REGNO(mem);
-+ dst_mem_reg = mem;
- else if (GET_CODE(mem) == CONST_INT)
- dst_mem_addr = INTVAL(mem);
- else if (GET_CODE(mem) == PLUS)
-@@ -652,7 +694,7 @@ insn_info::fledder (rtx set)
- rtx konst = XEXP(mem, 1);
- if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
- {
-- dst_mem_reg = REGNO(reg);
-+ dst_mem_reg = reg;
- dst_mem_addr = INTVAL(konst);
- }
- }
-@@ -660,15 +702,14 @@ insn_info::fledder (rtx set)
-
- if (REG_P(src))
- {
-- src_reg = true;
-- src_regno = REGNO(src);
-+ src_reg = src;
- }
- else if (MEM_P(src))
- {
- src_mem = true;
- rtx mem = XEXP(src, 0);
- if (REG_P(mem))
-- src_mem_regno = REGNO(mem);
-+ src_mem_reg = mem;
- else if (GET_CODE(mem) == CONST_INT)
- src_intval = INTVAL(mem);
- else if (GET_CODE(mem) == PLUS)
-@@ -678,7 +719,7 @@ insn_info::fledder (rtx set)
- rtx konst = XEXP(mem, 1);
- if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
- {
-- src_mem_regno = REGNO(reg);
-+ src_mem_reg = reg;
- src_const = true;
- src_intval = INTVAL(konst);
- }
-@@ -698,14 +739,13 @@ insn_info::fledder (rtx set)
- {
- if (GET_CODE(konst) == CONST_INT)
- {
-- src_regno = REGNO(reg);
-+ src_reg = reg;
- src_const = true;
- src_intval = INTVAL(konst);
- }
- else if (REG_P(konst))
- {
-- src_reg = true;
-- src_regno = REGNO(konst);
-+ src_reg = konst;
- }
- }
- }
-@@ -815,7 +855,7 @@ insn_info::plus_to_move (rtx_insn * newinsn)
- {
- insn = newinsn;
- src_plus = false;
-- src_reg = true;
-+ src_reg = XEXP(PATTERN (newinsn), 1);
- insn2index.insert (std::make_pair (insn, this));
- // usage flags did not change
- }
-@@ -834,7 +874,14 @@ insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
- }
-
- void
--insn_info::immediate2base (unsigned regno, unsigned base)
-+insn_info::set_insn (rtx_insn * newinsn)
++/* Return the address of the PCH address space, if the PCH will fit in it. */
++
++static void *
++amigaos_m68k_gt_pch_get_address (size_t sz ATTRIBUTE_UNUSED)
+{
-+ insn = newinsn;
-+ fledder (PATTERN (insn));
++ fatal_error ("PCH not supported\n");
+}
+
-+void
-+insn_info::absolute2base (unsigned regno, unsigned base)
- {
- rtx set = PATTERN (get_insn ());
- rtx src = SET_SRC(set);
-@@ -844,19 +891,18 @@ insn_info::immediate2base (unsigned regno, unsigned base)
- unsigned offset = addr - base;
-
- rtx pattern;
-+ rtx reg = gen_raw_REG (SImode, regno);
- if (base == addr)
-- pattern = gen_rtx_SET(gen_rtx_MEM (mode, gen_raw_REG (SImode, regno)), SET_SRC(set));
-+ pattern = gen_rtx_SET(gen_rtx_MEM (mode, reg), src);
- else
-- pattern = gen_rtx_SET(
-- gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, gen_raw_REG (SImode, regno), gen_rtx_CONST_INT(SImode, offset))),
-- SET_SRC(set));
-+ pattern = gen_rtx_SET(gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT(SImode, offset))), src);
-
- SET_INSN_DELETED(insn);
- insn = emit_insn_after (pattern, insn);
-
- mark_use (regno);
-
-- dst_mem_reg = regno;
-+ dst_mem_reg = reg;
- dst_mem = true;
- dst_mem_addr = offset;
- dst_plus = offset != 0;
-@@ -908,7 +954,7 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- insn_info & ii = *i->second;
-
- if (f != stderr)
-- fprintf (f, "\n\t\t\t\t\t\t| ");
-+ fprintf (f, "\n\t\t\t\t\t\t|%c ", ii.is_stack () ? 's' : ' ');
-
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j) || ii.is_def (j))
-@@ -1046,7 +1092,7 @@ update_insn_infos (void)
- if (!use.is_def (FIRST_PSEUDO_REGISTER))
- {
- CC_STATUS_INIT;
-- NOTICE_UPDATE_CC(PATTERN (insn), insn);
-+ NOTICE_UPDATE_CC (PATTERN (insn), insn);
- if (cc_status.value1 || cc_status.value2)
- use.mark_def (FIRST_PSEUDO_REGISTER);
- }
-@@ -1706,7 +1752,7 @@ opt_strcpy ()
- if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 && is_reg_dead (REGNO(dst), index))
- {
- /* now check via NOTICE_UPDATE_CC*/
-- NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
-+ NOTICE_UPDATE_CC (PATTERN (reg2x), reg2x);
- if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2))
- {
- int num_clobbers_to_add = 0;
-@@ -2074,13 +2120,13 @@ opt_merge_add (void)
- insn_info & ii1 = infos[index + 1];
- insn_info & ii2 = infos[index + 2];
-
-- if (!ii2.is_dst_reg () || ii2.is_dst_mem ())
-+ if (!ii2.is_dst_reg ())
- {
- index += 2;
- continue;
- }
-
-- if (!ii1.is_dst_reg () || ii1.is_dst_mem ())
-+ if (!ii1.is_dst_reg ())
- {
- ++index;
- continue;
-@@ -2089,7 +2135,7 @@ opt_merge_add (void)
- if (!ii0.is_dst_reg () || !ii0.is_src_plus () || !ii1.is_src_plus () || !ii2.is_src_plus ())
- continue;
-
-- if (ii0.is_src_mem () || !ii0.is_src_const () || !ii1.is_src_reg () || ii2.is_src_mem () || !ii2.is_src_const ())
-+ if (!ii0.is_src_const () || !ii2.is_src_const () || ii0.get_src_intval () != ii2.get_src_intval ())
- continue;
-
- if (ii0.get_dst_regno () != ii1.get_dst_regno () || ii1.get_src_regno () != ii2.get_dst_regno ())
-@@ -2098,7 +2144,7 @@ opt_merge_add (void)
- rtx_insn * insn1 = ii1.get_insn ();
++#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
++#define HOST_HOOKS_GT_PCH_GET_ADDRESS amigaos_m68k_gt_pch_get_address
++
++const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
+\ No newline at end of file
+diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
+index 03f474e1b63c..4533427db7a7 100644
+--- gcc/config/m68k/m68k.c
++++ gcc/config/m68k/m68k.c
+@@ -166,7 +166,10 @@ static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
+ static bool m68k_ok_for_sibcall_p (tree, tree);
+ static bool m68k_tls_symbol_p (rtx);
+ static rtx m68k_legitimize_address (rtx, rtx, machine_mode);
+-static bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
++#ifndef TARGET_AMIGA
++static
++#endif
++bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+ #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
+ static bool m68k_return_in_memory (const_tree, const_tree);
+ #endif
+@@ -174,10 +177,12 @@ static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
+ static void m68k_trampoline_init (rtx, tree, rtx);
+ static int m68k_return_pops_args (tree, tree, int);
+ static rtx m68k_delegitimize_address (rtx);
++#ifndef TARGET_AMIGA
+ static void m68k_function_arg_advance (cumulative_args_t, machine_mode,
+ const_tree, bool);
+ static rtx m68k_function_arg (cumulative_args_t, machine_mode,
+ const_tree, bool);
++#endif
+ static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
+ static bool m68k_output_addr_const_extra (FILE *, rtx);
+ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
+@@ -186,7 +191,11 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
- CC_STATUS_INIT;
-- NOTICE_UPDATE_CC(PATTERN (insn1), insn1);
-+ NOTICE_UPDATE_CC (PATTERN (insn1), insn1);
- if (cc_status.value1 || cc_status.value2)
- continue;
+ #if INT_OP_GROUP == INT_OP_DOT_WORD
+ #undef TARGET_ASM_ALIGNED_HI_OP
++#ifndef TARGET_AMIGAOS_VASM
+ #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
++#else
++#define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
++#endif
+ #endif
-@@ -2182,6 +2228,7 @@ opt_shrink_stack_frame (void)
- {
- rtx set = XVECEXP(pattern, 0, 0);
- rtx dst = SET_DEST(set);
-+ ii.mark_stack ();
- /* ignore link a5 */
- if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
- {
-@@ -2190,11 +2237,6 @@ opt_shrink_stack_frame (void)
- set = XVECEXP(pattern, 0, 2);
- a5offset = INTVAL(XEXP(SET_SRC(set), 1));
- }
-- else
-- {
-- /* use movem */
-- ii.mark_stack ();
-- }
- ++pos;
- continue;
- }
-@@ -2269,6 +2311,7 @@ opt_shrink_stack_frame (void)
- {
- rtx set = XVECEXP(pattern, 0, 0);
- rtx dst = SET_DEST(set);
-+ ii.mark_stack ();
- /* unlink is last. */
- if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
- {
-@@ -2276,8 +2319,6 @@ opt_shrink_stack_frame (void)
- break;
- }
+ #if INT_OP_GROUP == INT_OP_NO_DOT
+@@ -322,6 +331,10 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
+ #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
+ #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128
-- /* movem. */
-- ii.mark_stack ();
- }
- else if (GET_CODE(pattern) == SET)
- {
-@@ -2295,6 +2336,12 @@ opt_shrink_stack_frame (void)
- if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
- ii.mark_stack ();
- }
-+ else if (GET_CODE(postinc) == PLUS)
-+ {
-+ rtx a5 = XEXP(postinc, 0);
-+ if (REG_P(a5) && REGNO(a5) == FRAME_POINTER_REGNUM)
-+ ii.mark_stack ();
-+ }
- }
- }
- }
-@@ -2306,16 +2353,17 @@ opt_shrink_stack_frame (void)
- for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & jj = infos[i];
-- if (jj.is_stack ())
-+ if (jj.in_proepi ())
- continue;
++#ifdef TARGET_AMIGA
++#include "amigaos.h"
++#endif
++
+ static const struct attribute_spec m68k_attribute_table[] =
+ {
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
+@@ -332,6 +345,9 @@ static const struct attribute_spec m68k_attribute_table[] =
+ m68k_handle_fndecl_attribute, false },
+ { "interrupt_thread", 0, 0, true, false, false,
+ m68k_handle_fndecl_attribute, false },
++#ifdef SUBTARGET_ATTRIBUTES
++ SUBTARGET_ATTRIBUTES
++#endif
+ { NULL, 0, 0, false, false, false, NULL, false }
+ };
-- ii.merge (jj);
-+ ii.or_use (jj);
- }
-- unsigned freemask = ~ii.get_use ();
-+ unsigned freemask = ~ii.get_use () & 0x7fff;
+@@ -340,11 +356,21 @@ struct gcc_target targetm = TARGET_INITIALIZER;
+ /* Base flags for 68k ISAs. */
+ #define FL_FOR_isa_00 FL_ISA_68000
+ #define FL_FOR_isa_10 (FL_FOR_isa_00 | FL_ISA_68010)
+-/* FL_68881 controls the default setting of -m68881. gcc has traditionally
++/* "FL_68881 controls the default setting of -m68881. gcc has traditionally
+ generated 68881 code for 68020 and 68030 targets unless explicitly told
+- not to. */
++ not to."
++
++ This is not true at least for the AMIGA.
++ gcc 2.93 does not set the 68881 flag.
++
++ */
++#ifdef TARGET_AMIGA
++#define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
++ | FL_BITFIELD | FL_CAS)
++#else
+ #define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
+ | FL_BITFIELD | FL_68881 | FL_CAS)
++#endif
+ #define FL_FOR_isa_40 (FL_FOR_isa_20 | FL_ISA_68040)
+ #define FL_FOR_isa_cpu32 (FL_FOR_isa_10 | FL_ISA_68020)
- rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
- rtx a5 = gen_raw_REG (SImode, FRAME_POINTER_REGNUM);
+@@ -545,7 +571,7 @@ m68k_option_override (void)
+ : (m68k_cpu_flags & FL_COLDFIRE) != 0 ? FPUTYPE_COLDFIRE
+ : FPUTYPE_68881);
-+ unsigned changed = 0;
- unsigned adjust = 0;
- /* now all push/pop insns are in temp. */
- for (unsigned i = 0; i < infos.size (); ++i)
-@@ -2339,8 +2387,8 @@ opt_shrink_stack_frame (void)
- clobbers.push_back (set);
- continue;
- }
-- rtx src = SET_SRC(set);
- rtx dst = SET_DEST(set);
-+ rtx src = SET_SRC(set);
- rtx reg;
- if (MEM_P(src))
- reg = dst;
-@@ -2349,6 +2397,13 @@ opt_shrink_stack_frame (void)
- else
- continue;
+- /* Sanity check to ensure that msep-data and mid-sahred-library are not
++ /* Sanity check to ensure that msep-data and mid-shared-library are not
+ * both specified together. Doing so simply doesn't make sense.
+ */
+ if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
+@@ -556,7 +582,7 @@ m68k_option_override (void)
+ * -fpic but it hasn't been tested properly.
+ */
+ if (TARGET_SEP_DATA || TARGET_ID_SHARED_LIBRARY)
+- flag_pic = 2;
++ flag_pic = TARGET_68020 ? 2 : 1;
-+ if (REGNO(reg) == FRAME_POINTER_REGNUM)
-+ {
-+ // mark as "do not touch"
-+ clobbers.push_back (reg);
-+ break;
-+ }
-+
- if (i < prologueend)
- paramstart += 4;
- unsigned regbit = 1 << REGNO(reg);
-@@ -2378,6 +2433,7 @@ opt_shrink_stack_frame (void)
- log ("shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1, regs.size ());
- if (regs.size () <= 2)
- {
-+ changed = 1;
- for (unsigned k = 0; k < regs.size (); ++k)
- {
- rtx reg = regs[k];
-@@ -2453,6 +2509,7 @@ opt_shrink_stack_frame (void)
- emit_insn_after (parallel, insn);
- }
- SET_INSN_DELETED(insn);
-+ changed = 1;
- }
- }
- else
-@@ -2470,6 +2527,7 @@ opt_shrink_stack_frame (void)
- adjust += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
- log ("remove push for %s\n", reg_names[REGNO(src)]);
- SET_INSN_DELETED(insn);
-+ ++changed;
- }
- }
- else
-@@ -2481,6 +2539,7 @@ opt_shrink_stack_frame (void)
- {
- log ("remove pop for %s\n", reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
-+ ++changed;
- }
- }
- }
-@@ -2524,42 +2583,47 @@ opt_shrink_stack_frame (void)
+ /* -mpcrel -fPIC uses 32-bit pc-relative displacements. Raise an
+ error if the target does not support them. */
+@@ -569,11 +595,15 @@ m68k_option_override (void)
+ if (TARGET_PCREL && flag_pic == 0)
+ flag_pic = 1;
- if (usea5 && a5offset == -4)
+- if (!flag_pic)
++ /* SBF: use normal jumps/calls with baserel(32) modes. */
++ if (!flag_pic || flag_pic > 2)
{
-- for (std::vector<int>::iterator i = a5pos.begin (); i != a5pos.end (); ++i)
-- {
-- insn_info & ii = infos[*i];
-- ii.mark_stack ();
-- }
-- for (unsigned i = 0; i < infos.size (); ++i)
-- {
-- insn_info ii;
-- insn_info & jj = infos[i];
-- if (jj.is_stack ())
-- continue;
--
-- ii.merge (jj);
-- }
-- unsigned freemask = ~ii.get_use ();
+ m68k_symbolic_call_var = M68K_SYMBOLIC_CALL_JSR;
-
- if (freemask & (1 << FRAME_POINTER_REGNUM))
- {
- log ("dropping unused frame pointer\n");
- for (std::vector<int>::iterator i = a5pos.begin (); i != a5pos.end (); ++i)
- SET_INSN_DELETED(infos[*i].get_insn ());
-+
-+ /* convert parameter access via a5 into a7. */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+
-+ if (ii.is_dst_reg () && ii.get_src_mem_regno () == FRAME_POINTER_REGNUM)
-+ {
-+ rtx x = gen_rtx_CONST_INT (SImode, ii.get_src_intval () - 4);
-+ rtx p = gen_rtx_PLUS(SImode, a7, x);
-+ rtx pattern = gen_rtx_SET(copy_reg (ii.get_dst_reg (), -1), gen_rtx_MEM (SImode, p));
-+ set_insn_deleted (ii.get_insn ());
-+ rtx_insn * newinsn = emit_insn_after (pattern, ii.get_insn ());
-+ ii.plus_to_move (newinsn);
-+ }
-+ }
-+
-+ ++changed;
- }
++#ifndef TARGET_AMIGAOS_VASM
+ m68k_symbolic_jump = "jra %a0";
++#else
++ m68k_symbolic_jump = "jmp %a0";
++#endif
}
-
-- return 0;
-+ return changed;
- }
-
-+/*
-+ * Convert a series of move into absolute address into register based moves.
-+ */
- static unsigned
--opt_immediate (void)
-+opt_absolute (void)
- {
- unsigned change_count = 0;
-
- for (unsigned i = 0; i < infos.size (); ++i)
+ else if (TARGET_ID_SHARED_LIBRARY)
+ /* All addresses must be loaded from the GOT. */
+@@ -866,8 +896,9 @@ m68k_save_reg (unsigned int regno, bool interrupt_handler)
{
- insn_info & ii = infos[i];
-- if (!ii.is_dst_mem () || !ii.has_dst_addr () || ii.has_dst_memreg())
-+ if (!ii.is_dst_mem () || !ii.has_dst_addr () || ii.has_dst_memreg ())
- continue;
-
- unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00;
-@@ -2580,7 +2644,7 @@ opt_immediate (void)
- if (!freemask)
- break;
-
-- if (jj.is_dst_mem () && jj.has_dst_addr () && !jj.has_dst_memreg())
-+ if (jj.is_dst_mem () && jj.has_dst_addr () && !jj.has_dst_memreg ())
- {
- unsigned addr = jj.get_dst_addr ();
- if (addr < base)
-@@ -2600,20 +2664,20 @@ opt_immediate (void)
- for (auto k = found.begin (); k != found.end (); ++k)
- {
- insn_info & kk = infos[*k];
-- kk.immediate2base (regno, base);
-+ kk.absolute2base (regno, base);
- }
-
- // load base into reg
- rtx lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
- rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
- insn_info nn (insn);
-- nn.set_use(ii.get_use());
-- nn.scan();
-+ nn.set_use (ii.get_use ());
-+ nn.scan ();
- nn.fledder (lea);
- nn.mark_def (regno);
- infos.insert (infos.begin () + i, nn);
- while (i++ < j)
-- infos[i].mark_use(regno);
-+ infos[i].mark_use (regno);
- ++j;
- ++change_count;
- }
-@@ -2686,7 +2750,7 @@ namespace
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
- be_very_verbose = strchr (string_bbb_opts, 'V');
-- be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v');
-+ be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v') || 1;
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-@@ -2696,7 +2760,7 @@ namespace
- bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr (string_bbb_opts, '+');
- bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
- bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
-- bool do_immediate = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
-+ bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
-
- for (;;)
- {
-@@ -2720,8 +2784,8 @@ namespace
- if (do_elim_dead_assign && opt_elim_dead_assign ())
- done = 0, update_insns ();
-
-- if (do_immediate && opt_immediate ())
-- done = 0, update_insns ();
-+ if (do_absolute && opt_absolute ())
-+ done = 0;
-
- if (do_bb_reg_rename)
- {
-@@ -2738,8 +2802,8 @@ namespace
-
- if (do_shrink_stack_frame)
- {
-- opt_shrink_stack_frame ();
-- update_insns ();
-+ if (opt_shrink_stack_frame ())
-+ update_insns ();
- }
-
- if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-index b3818a80846d..1ed6557ee713 100755
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -406,8 +406,9 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
-
- /* In the first pass, we force the renaming of registers that
- don't belong to PREFERRED_CLASS to registers that do, even
-- though the latters were used not very long ago. */
-- if ((pass == 0
-+ though the latters were used not very long ago.
-+ Also use a register if no best_new_reg was found till now */
-+ if (((pass == 0 || !has_preferred_class)
- && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
- best_new_reg))
- || tick[best_new_reg] > tick[new_reg])
-
-From f3a773accb47542fef665cf044dad13366139ab5 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 3 May 2017 09:33:02 +0200
-Subject: [PATCH 107/303] @B fix shrink stack frame for 8 byte parameters
-
----
- gcc/bbb-opts.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 6a27fcf72544..e8000a01ce49 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2598,7 +2598,8 @@ opt_shrink_stack_frame (void)
- {
- rtx x = gen_rtx_CONST_INT (SImode, ii.get_src_intval () - 4);
- rtx p = gen_rtx_PLUS(SImode, a7, x);
-- rtx pattern = gen_rtx_SET(copy_reg (ii.get_dst_reg (), -1), gen_rtx_MEM (SImode, p));
-+ rtx pattern = gen_rtx_SET(copy_reg (ii.get_dst_reg (), -1),
-+ gen_rtx_MEM (GET_MODE(ii.get_dst_reg ()), p));
- set_insn_deleted (ii.get_insn ());
- rtx_insn * newinsn = emit_insn_after (pattern, ii.get_insn ());
- ii.plus_to_move (newinsn);
-
-From c391e554b0a0d6fad5b78ed5ace23eab60cbbe3d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 3 May 2017 12:57:04 +0200
-Subject: [PATCH 108/303] @N opt_absolute also optimizes symbol refs
-
----
- gcc/bbb-opts.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 98 insertions(+), 8 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index e8000a01ce49..d54da597123b 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -81,6 +81,7 @@ bool be_verbose;
- #define STACK_POINTER_REGNUM 15
- #define NOTICE_UPDATE_CC(a,b)
- #define Pmode SImode
-+#define PIC_REG 12
- #endif
- extern struct lang_hooks lang_hooks;
-
-@@ -151,8 +152,10 @@ class insn_info
+ if (crtl->saves_all_registers)
+ return true;
++ /* SBF: do not save the PIC_REG with baserel(32) modes. */
+ if (crtl->uses_pic_offset_table)
+- return true;
++ return flag_pic < 3;
+ /* Reload may introduce constant pool references into a function
+ that thitherto didn't need a PIC register. Note that the test
+ above will not catch that case because we will only set
+@@ -978,6 +1009,8 @@ m68k_set_frame_related (rtx_insn *insn)
- rtx dst_reg;
- rtx dst_mem_reg;
-+ rtx dst_symbol;
- rtx src_reg;
- rtx src_mem_reg;
-+ rtx src_symbol;
- unsigned dst_mem_addr;
+ /* Emit RTL for the "prologue" define_expand. */
- unsigned src_intval;
-@@ -161,7 +164,8 @@ class insn_info
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_const (
-- false), dst_reg (0), dst_mem_reg (0), src_reg (0), src_mem_reg (0), dst_mem_addr (0), src_intval (0)
-+ false), dst_reg (0), dst_mem_reg (0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (
-+ 0), src_intval (0)
- {
- }
++extern void amiga_emit_regparm_clobbers(void);
++
+ void
+ m68k_expand_prologue (void)
+ {
+@@ -986,6 +1019,10 @@ m68k_expand_prologue (void)
-@@ -201,6 +205,12 @@ class insn_info
- return dst_mem_reg;
- }
+ m68k_compute_frame_layout ();
-+ inline rtx
-+ get_dst_symbol () const
-+ {
-+ return dst_symbol;
-+ }
++#ifdef TARGET_AMIGA
++ amiga_emit_regparm_clobbers();
++#endif
+
- inline bool
- has_dst_addr () const
- {
-@@ -687,6 +697,8 @@ insn_info::fledder (rtx set)
- dst_mem_reg = mem;
- else if (GET_CODE(mem) == CONST_INT)
- dst_mem_addr = INTVAL(mem);
-+ else if (GET_CODE(mem) == SYMBOL_REF)
-+ dst_symbol = mem;
- else if (GET_CODE(mem) == PLUS)
- {
- dst_plus = true;
-@@ -698,6 +710,20 @@ insn_info::fledder (rtx set)
- dst_mem_addr = INTVAL(konst);
- }
- }
-+ else if (GET_CODE(mem) == CONST)
-+ {
-+ mem = XEXP(mem, 0);
-+ if (GET_CODE(mem) == PLUS)
-+ {
-+ rtx sym = XEXP(mem, 0);
-+ if (GET_CODE(sym) == SYMBOL_REF)
-+ {
-+ dst_plus = true;
-+ dst_symbol = sym;
-+ dst_mem_addr = INTVAL(XEXP(mem, 1));
-+ }
-+ }
-+ }
- }
+ if (flag_stack_usage_info)
+ current_function_static_stack_size
+ = current_frame.size + current_frame.offset;
+@@ -1021,6 +1058,11 @@ m68k_expand_prologue (void)
- if (REG_P(src))
-@@ -712,6 +738,8 @@ insn_info::fledder (rtx set)
- src_mem_reg = mem;
- else if (GET_CODE(mem) == CONST_INT)
- src_intval = INTVAL(mem);
-+ else if (GET_CODE(mem) == SYMBOL_REF)
-+ src_symbol = mem;
- else if (GET_CODE(mem) == PLUS)
- {
- src_plus = true;
-@@ -724,6 +752,20 @@ insn_info::fledder (rtx set)
- src_intval = INTVAL(konst);
- }
- }
-+ else if (GET_CODE(mem) == CONST)
-+ {
-+ mem = XEXP(mem, 0);
-+ if (GET_CODE(mem) == PLUS)
-+ {
-+ rtx sym = XEXP(mem, 0);
-+ if (GET_CODE(sym) == SYMBOL_REF)
-+ {
-+ src_plus = true;
-+ src_symbol = sym;
-+ src_intval = INTVAL(XEXP(mem, 1));
-+ }
-+ }
-+ }
- }
- else if (GET_CODE(src) == CONST_INT)
+ if (frame_pointer_needed)
{
-@@ -749,7 +791,6 @@ insn_info::fledder (rtx set)
- }
++#ifdef TARGET_AMIGA
++ if (HAVE_ALTERNATE_FRAME_SETUP_F (fsize_with_regs))
++ ALTERNATE_FRAME_SETUP_F (fsize_with_regs);
++ else
++#endif
+ if (fsize_with_regs == 0 && TUNE_68040)
+ {
+ /* On the 68040, two separate moves are faster than link.w 0. */
+@@ -1030,6 +1072,10 @@ m68k_expand_prologue (void)
+ m68k_set_frame_related (emit_move_insn (frame_pointer_rtx,
+ stack_pointer_rtx));
}
++#ifdef TARGET_AMIGA
++ else if (HAVE_ALTERNATE_FRAME_SETUP (fsize_with_regs))
++ ALTERNATE_FRAME_SETUP (fsize_with_regs);
++#endif
+ else if (fsize_with_regs < 0x8000 || TARGET_68020)
+ m68k_set_frame_related
+ (emit_insn (gen_link (frame_pointer_rtx,
+@@ -1127,9 +1173,14 @@ m68k_expand_prologue (void)
+ current_frame.reg_mask, true, true));
}
--
- }
-
- /* create a copy for a reg. Optional specify a new register number. */
-@@ -813,6 +854,7 @@ static std::vector<rtx_insn *> jumps;
- static std::map<rtx_insn *, insn_info *> insn2index;
-
- static insn_info * info0;
-+static unsigned usable_regs;
- static void
- update_insn2index ()
-@@ -1107,6 +1149,27 @@ update_insn_infos (void)
- }
- ++pass;
- }
-+
-+ /* fill the mask of general used regs. */
-+ insn_info zz;
-+ for (int i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (ii.in_proepi () != 1)
-+ break;
-+
-+ zz.or_use (ii);
-+ }
-+
-+ /* always allow a0/a1, d0/d1. */
-+ usable_regs = zz.get_use () | 0x303;
-+ if (flag_pic)
-+ usable_regs &= ~(1 << PIC_REG);
-+
-+ if (infos.size () && infos[0].is_use (FRAME_POINTER_REGNUM))
-+ usable_regs &= ~(1 << FRAME_POINTER_REGNUM);
++ /* SBF: do not load the PIC_REG with baserel(32) */
+ if (!TARGET_SEP_DATA
+- && crtl->uses_pic_offset_table)
++ && crtl->uses_pic_offset_table && flag_pic < 3)
+ emit_insn (gen_load_got (pic_offset_table_rtx));
+
-+ usable_regs &= ~(1 << STACK_POINTER_REGNUM);
++#ifdef TARGET_AMIGA
++ amigaos_restore_a4 ();
++#endif
+ }
+
+ /* Return true if a simple (return) instruction is sufficient for this
+@@ -1419,6 +1470,7 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
+ return false;
}
- /*
-@@ -2627,10 +2690,12 @@ opt_absolute (void)
- if (!ii.is_dst_mem () || !ii.has_dst_addr () || ii.has_dst_memreg ())
- continue;
-
-- unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00;
-+ unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00 & usable_regs;
- if (!freemask)
- continue;
++#ifndef TARGET_AMIGA
+ /* On the m68k all args are always pushed. */
-+ rtx with_symbol = ii.get_dst_symbol ();
-+
- std::vector<unsigned> found;
- found.push_back (i);
- unsigned base = ii.get_dst_addr ();
-@@ -2645,22 +2710,35 @@ opt_absolute (void)
- if (!freemask)
- break;
+ static rtx
+@@ -1440,6 +1492,7 @@ m68k_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
+ ? (GET_MODE_SIZE (mode) + 3) & ~3
+ : (int_size_in_bytes (type) + 3) & ~3);
+ }
++#endif
-- if (jj.is_dst_mem () && jj.has_dst_addr () && !jj.has_dst_memreg ())
-+ if (jj.is_dst_mem () && jj.has_dst_addr () && !jj.has_dst_memreg () && jj.get_dst_symbol () == with_symbol)
+ /* Convert X to a legitimate function call memory reference and return the
+ result. */
+@@ -1796,13 +1849,21 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx_insn *insn, int signpos
+ && next_insn_tests_no_inequality (insn))
{
- unsigned addr = jj.get_dst_addr ();
- if (addr < base)
- base = addr;
-- if (addr - base > 0x7ffc)
-- continue;
-
- found.push_back (j);
+ cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N | CC_NO_OVERFLOW;
++#ifndef TARGET_AMIGAOS_VASM
+ return "move%.w %1,%%ccr";
++#else
++ return "move%.w %1,ccr";
++#endif
}
- }
-
-+ if (freemask && found.size () > 2)
-+ {
-+ /* check again. */
-+ for (auto k = found.begin (); k != found.end ();)
-+ {
-+ insn_info & kk = infos[*k];
-+ if (kk.get_dst_addr () - base > 0x7ffc)
-+ found.erase (k);
-+ else
-+ ++k;
-+ }
-+ }
- if (freemask && found.size () > 2)
- {
- unsigned regno = bit2regno (freemask);
-- log ("modifying %d immediate using %s\n", found.size (), reg_names[regno]);
-+ if (with_symbol)
-+ log ("modifying %d symbol addresses using %s\n", found.size (), reg_names[regno]);
-+ else
-+ log ("modifying %d absolute addresses using %s\n", found.size (), reg_names[regno]);
-
- for (auto k = found.begin (); k != found.end (); ++k)
+ if (count == 2 && DATA_REG_P (operands[1])
+ && next_insn_tests_no_inequality (insn))
{
-@@ -2669,7 +2747,19 @@ opt_absolute (void)
+ cc_status.flags = CC_NOT_NEGATIVE | CC_INVERTED | CC_NO_OVERFLOW;
++#ifndef TARGET_AMIGAOS_VASM
+ return "move%.w %1,%%ccr";
++#else
++ return "move%.w %1,ccr";
++#endif
}
+ /* count == 1 followed by bvc/bvs and
+ count == 0 followed by bcc/bcs are also possible, but need
+@@ -1921,10 +1982,12 @@ m68k_legitimate_constant_address_p (rtx x, unsigned int reach, bool strict_p)
+ if (!CONSTANT_ADDRESS_P (x))
+ return false;
- // load base into reg
-- rtx lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
-+ rtx lea;
-+
-+ if (with_symbol)
-+ {
-+ if (base)
-+ lea = gen_rtx_SET(
-+ gen_raw_REG (SImode, regno),
-+ gen_rtx_CONST(SImode, gen_rtx_PLUS(SImode, with_symbol, gen_rtx_CONST_INT (SImode, base))));
-+ else
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), with_symbol);
-+ }
-+ else
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
- rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
- insn_info nn (insn);
- nn.set_use (ii.get_use ());
-
-From 09c30ec6c5e0bd07fa3d300c2d45cec75f67c783 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 4 May 2017 11:42:43 +0200
-Subject: [PATCH 109/303] @B fix dropping stack frame - now only dropped if
- really unused
-
----
- gcc/bbb-opts.c | 246 +++++++++++++++++++++++++++++++++++++++++++++------------
- 1 file changed, 197 insertions(+), 49 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index d54da597123b..a4bb1e0a97a3 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -150,6 +150,8 @@ class insn_info
- bool src_plus;
- bool src_const;
-
-+ machine_mode mode;
-+
- rtx dst_reg;
- rtx dst_mem_reg;
- rtx dst_symbol;
-@@ -158,14 +160,14 @@ class insn_info
- rtx src_symbol;
- unsigned dst_mem_addr;
-
-- unsigned src_intval;
-+ unsigned src_mem_addr;
-
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_const (
-- false), dst_reg (0), dst_mem_reg (0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (
-- 0), src_intval (0)
-+ false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (
-+ 0), dst_mem_addr (0), src_mem_addr (0)
- {
- }
-
-@@ -179,7 +181,7 @@ class insn_info
- swap_adds (rtx_insn * newinsn, insn_info & ii);
-
- void
-- absolute2base (unsigned regno, unsigned base);
-+ absolute2base (unsigned regno, unsigned base, rtx with_symbol);
-
- inline bool
- is_dst_reg () const
-@@ -205,18 +207,35 @@ class insn_info
- return dst_mem_reg;
- }
-
-+ inline bool
-+ has_src_memreg () const
-+ {
-+ return src_mem_reg;
-+ }
-+
- inline rtx
- get_dst_symbol () const
- {
- return dst_symbol;
- }
-
-+ inline rtx
-+ get_src_symbol () const
-+ {
-+ return src_symbol;
-+ }
- inline bool
- has_dst_addr () const
- {
- return dst_mem_addr;
- }
+- if (flag_pic
++ if (flag_pic && flag_pic < 3
+ && !(strict_p && TARGET_PCREL)
+ && symbolic_operand (x, VOIDmode))
+- return false;
++ {
++ return false;
++ }
-+ inline bool
-+ has_src_addr () const
-+ {
-+ return src_mem_addr;
-+ }
-+
- inline bool
- is_label () const
- {
-@@ -241,6 +260,12 @@ class insn_info
- return dst_mem_addr;
- }
+ if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P && reach > 1)
+ {
+@@ -2111,6 +2174,18 @@ m68k_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
+ {
+ struct m68k_address address;
-+ inline unsigned
-+ get_src_addr () const
-+ {
-+ return src_mem_addr;
-+ }
++#ifdef TARGET_AMIGA
++ if (MEM_P(x))
++ return false;
++ /* SBF: the baserel(32) const plus pic_ref, symbol is an address. */
++ if (amiga_is_const_pic_ref(x))
++ return true;
+
- inline bool
- is_src_reg () const
- {
-@@ -292,7 +317,7 @@ class insn_info
- inline int
- get_src_intval () const
- {
-- return src_intval;
-+ return src_mem_addr;
- }
-
- inline bool
-@@ -401,6 +426,12 @@ class insn_info
- return use;
- }
-
-+ inline unsigned
-+ get_myuse () const
-+ {
-+ return myuse;
-+ }
++ if (!amigaos_legitimate_src(x))
++ return false;
+
- inline void
- set_use (unsigned u)
- {
-@@ -467,6 +498,7 @@ class insn_info
- inline insn_info &
- merge (insn_info const & o)
- {
-+ myuse = o.myuse;
- use = (use & ~o.def) | o.use;
- def |= o.def;
- hard |= o.hard;
-@@ -577,6 +609,8 @@ class insn_info
- void
- set_insn (rtx_insn * newinsn);
-
-+ void
-+ a5_to_a7 (rtx a7);
- };
-
- void
-@@ -677,6 +711,8 @@ insn_info::fledder (rtx set)
- rtx dst = SET_DEST(set);
- rtx src = SET_SRC(set);
-
-+ mode = GET_MODE(dst);
++#endif
+
- if (dst == cc0_rtx)
- {
- compare = true;
-@@ -737,7 +773,7 @@ insn_info::fledder (rtx set)
- if (REG_P(mem))
- src_mem_reg = mem;
- else if (GET_CODE(mem) == CONST_INT)
-- src_intval = INTVAL(mem);
-+ src_mem_addr = INTVAL(mem);
- else if (GET_CODE(mem) == SYMBOL_REF)
- src_symbol = mem;
- else if (GET_CODE(mem) == PLUS)
-@@ -749,7 +785,7 @@ insn_info::fledder (rtx set)
- {
- src_mem_reg = reg;
- src_const = true;
-- src_intval = INTVAL(konst);
-+ src_mem_addr = INTVAL(konst);
- }
- }
- else if (GET_CODE(mem) == CONST)
-@@ -762,7 +798,7 @@ insn_info::fledder (rtx set)
- {
- src_plus = true;
- src_symbol = sym;
-- src_intval = INTVAL(XEXP(mem, 1));
-+ src_mem_addr = INTVAL(XEXP(mem, 1));
- }
- }
- }
-@@ -770,7 +806,7 @@ insn_info::fledder (rtx set)
- else if (GET_CODE(src) == CONST_INT)
- {
- src_const = true;
-- src_intval = INTVAL(src);
-+ src_mem_addr = INTVAL(src);
- }
- else if (GET_CODE(src) == PLUS)
- {
-@@ -783,7 +819,7 @@ insn_info::fledder (rtx set)
- {
- src_reg = reg;
- src_const = true;
-- src_intval = INTVAL(konst);
-+ src_mem_addr = INTVAL(konst);
- }
- else if (REG_P(konst))
- {
-@@ -915,6 +951,42 @@ insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
- // usage flags did not change
+ return m68k_decompose_address (mode, x, strict_p, &address);
}
-+static
-+void
-+replace_reg (rtx x, unsigned regno, rtx newreg, int offset)
-+{
-+ RTX_CODE code = GET_CODE(x);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ {
-+ rtx y = XEXP(x, i);
-+ if (REG_P(y) && REGNO(y) == regno)
-+ {
-+ XEXP(x, i) = newreg;
-+ if (offset && i + 1 < GET_RTX_LENGTH(code))
-+ {
-+ rtx c = XEXP(x, i + 1);
-+ if (GET_CODE(c) == CONST_INT)
-+ XEXP(x, i + 1) = gen_rtx_CONST_INT (GET_MODE(x), INTVAL(c) + offset);
-+ }
-+ }
-+ else
-+ replace_reg (y, regno, newreg, offset);
-+ }
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ replace_reg (XVECEXP(x, i, j), regno, newreg, offset);
-+ }
-+}
-+
-+void
-+insn_info::a5_to_a7 (rtx a7)
-+{
-+ replace_reg (PATTERN (insn), FRAME_POINTER_REGNUM, a7, -4);
-+}
-+
- void
- insn_info::set_insn (rtx_insn * newinsn)
+@@ -2131,7 +2206,11 @@ m68k_legitimate_mem_p (rtx x, struct m68k_address *address)
+ bool
+ m68k_legitimate_constant_p (machine_mode mode, rtx x)
{
-@@ -923,32 +995,63 @@ insn_info::set_insn (rtx_insn * newinsn)
+- return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x);
++ return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x)
++#ifdef TARGET_AMIGA
++ && amigaos_legitimate_src (x)
++#endif
++ ;
}
- void
--insn_info::absolute2base (unsigned regno, unsigned base)
-+insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- {
- rtx set = PATTERN (get_insn ());
- rtx src = SET_SRC(set);
-- machine_mode mode = GET_MODE(SET_DEST(set));
--
-- unsigned addr = get_dst_addr ();
-- unsigned offset = addr - base;
-+ rtx dst = SET_DEST(set);
-+ machine_mode mode = GET_MODE(dst);
+ /* Return true if X matches the 'Q' constraint. It must be a memory
+@@ -2172,6 +2251,8 @@ m68k_get_gp (void)
+ if (pic_offset_table_rtx == NULL_RTX)
+ pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_REG);
- rtx pattern;
- rtx reg = gen_raw_REG (SImode, regno);
-- if (base == addr)
-- pattern = gen_rtx_SET(gen_rtx_MEM (mode, reg), src);
-- else
-- pattern = gen_rtx_SET(gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT(SImode, offset))), src);
++// debug_rtx(pic_offset_table_rtx);
+
-+ if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) && !has_dst_memreg () && get_dst_symbol () == with_symbol)
-+ {
-+ unsigned addr = get_dst_addr ();
-+ unsigned offset = addr - base;
-+ if (offset <= 0x7ffe)
+ crtl->uses_pic_offset_table = 1;
+
+ return pic_offset_table_rtx;
+@@ -2442,9 +2523,37 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
+ if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
+ {
+ gcc_assert (reg);
++ if (flag_pic < 3)
+ {
-+ rtx olddst = dst;
-+ if (base == addr)
-+ dst = gen_rtx_MEM (mode, reg);
-+ else
-+ dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-+
-+ if (src_plus && rtx_equal_p (olddst, XEXP(src, 0)))
-+ XEXP(src, 0) = dst;
-+
-+ dst_mem_reg = reg;
-+ dst_mem = true;
-+ dst_mem_addr = offset;
-+ dst_plus = offset != 0;
++ pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
++ pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
+ }
-+ }
-+
-+ if (is_src_mem () && (has_src_addr () || get_src_symbol ()) && !has_src_memreg () && get_src_symbol () == with_symbol)
-+ {
-+ unsigned addr = get_src_addr ();
-+ unsigned offset = addr - base;
-+ if (offset <= 0x7ffe)
++ #ifdef TARGET_AMIGA
++ else
+ {
-+ if (base == addr)
-+ src = gen_rtx_MEM (mode, reg);
-+ else
-+ src = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-+
-+ src_mem_reg = reg;
-+ src_mem = true;
-+ src_mem_addr = offset;
-+ src_plus = offset != 0;
-+ }
-+ }
+
-+ pattern = gen_rtx_SET(dst, src);
-
- SET_INSN_DELETED(insn);
- insn = emit_insn_after (pattern, insn);
-
- mark_use (regno);
-
-- dst_mem_reg = reg;
-- dst_mem = true;
-- dst_mem_addr = offset;
-- dst_plus = offset != 0;
--
- insn2index.insert (std::make_pair (insn, this));
- }
- /*
-@@ -2646,29 +2749,29 @@ opt_shrink_stack_frame (void)
-
- if (usea5 && a5offset == -4)
- {
-+ /* for now only drop the frame pointer if it's not used.
-+ * Needs tracking of the sp to adjust the offsets.
++ /* SBF: Does the symbol use common or bss and qualifies for pic_reg?
++ * Do not ref to .text via pic_reg!
+ */
- if (freemask & (1 << FRAME_POINTER_REGNUM))
- {
- log ("dropping unused frame pointer\n");
-- for (std::vector<int>::iterator i = a5pos.begin (); i != a5pos.end (); ++i)
-- SET_INSN_DELETED(infos[*i].get_insn ());
-+ for (auto i = a5pos.rbegin (); i != a5pos.rend (); ++i)
-+ {
-+ SET_INSN_DELETED(infos[*i].get_insn ());
-+ infos.erase (infos.begin () + *i);
-+ }
-
-- /* convert parameter access via a5 into a7. */
-+ /* convert all parameter accesses via a5 into a7. */
- for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & ii = infos[i];
-+ if (ii.get_myuse () & (1 << FRAME_POINTER_REGNUM))
-+ ii.a5_to_a7 (a7);
-
-- if (ii.is_dst_reg () && ii.get_src_mem_regno () == FRAME_POINTER_REGNUM)
-- {
-- rtx x = gen_rtx_CONST_INT (SImode, ii.get_src_intval () - 4);
-- rtx p = gen_rtx_PLUS(SImode, a7, x);
-- rtx pattern = gen_rtx_SET(copy_reg (ii.get_dst_reg (), -1),
-- gen_rtx_MEM (GET_MODE(ii.get_dst_reg ()), p));
-- set_insn_deleted (ii.get_insn ());
-- rtx_insn * newinsn = emit_insn_after (pattern, ii.get_insn ());
-- ii.plus_to_move (newinsn);
-- }
-+ ii.unset (FRAME_POINTER_REGNUM);
- }
-
-+ update_insn2index ();
- ++changed;
- }
- }
-@@ -2687,18 +2790,23 @@ opt_absolute (void)
- for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & ii = infos[i];
-- if (!ii.is_dst_mem () || !ii.has_dst_addr () || ii.has_dst_memreg ())
-+
-+ bool is_dst = ii.is_dst_mem () && (ii.has_dst_addr () || ii.get_dst_symbol ()) && !ii.has_dst_memreg ();
-+ bool is_src = ii.is_src_mem () && (ii.has_src_addr () || ii.get_src_symbol ()) && !ii.has_src_memreg ();
-+
-+ if (!is_dst && !is_src)
- continue;
-
- unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00 & usable_regs;
- if (!freemask)
- continue;
-
-- rtx with_symbol = ii.get_dst_symbol ();
-+ rtx with_symbol = is_dst ? ii.get_dst_symbol () : ii.get_src_symbol ();
-
- std::vector<unsigned> found;
- found.push_back (i);
- unsigned base = ii.get_dst_addr ();
-+ unsigned max = base;
- unsigned j = i + 1;
- for (; j < infos.size (); ++j)
- {
-@@ -2710,13 +2818,49 @@ opt_absolute (void)
- if (!freemask)
- break;
-
-- if (jj.is_dst_mem () && jj.has_dst_addr () && !jj.has_dst_memreg () && jj.get_dst_symbol () == with_symbol)
-+ bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ()) && !jj.has_dst_memreg ()
-+ && jj.get_dst_symbol () == with_symbol;
-+ bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ()) && !jj.has_src_memreg ()
-+ && jj.get_src_symbol () == with_symbol;
-+ if (j_dst)
- {
- unsigned addr = jj.get_dst_addr ();
- if (addr < base)
-- base = addr;
--
-- found.push_back (j);
-+ {
-+ if (max - addr <= 0x7ffe)
-+ {
-+ base = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ else if (addr - base <= 0x7ffe)
-+ {
-+ if (addr > max)
-+ max = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ if (j_src)
++ tree decl;
++ if (GET_CODE (orig) == SYMBOL_REF && !orig->frame_related && !SYMBOL_REF_FUNCTION_P(orig)
++ && (decl = SYMBOL_REF_DECL (orig)) && !(DECL_SECTION_NAME(decl))
++ && !decl->common.typed.base.readonly_flag
++ && !decl->decl_with_vis.in_text_section)
+ {
-+ unsigned addr = jj.get_src_addr ();
-+ if (addr < base)
-+ {
-+ if (max - addr <= 0x7ffe)
-+ {
-+ base = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ else if (addr - base <= 0x7ffe)
-+ {
-+ if (addr > max)
-+ max = addr;
-+ found.push_back (j);
-+ continue;
-+ }
- }
- }
-
-@@ -2743,7 +2887,7 @@ opt_absolute (void)
- for (auto k = found.begin (); k != found.end (); ++k)
- {
- insn_info & kk = infos[*k];
-- kk.absolute2base (regno, base);
-+ kk.absolute2base (regno, base, with_symbol);
- }
- // load base into reg
-@@ -2767,13 +2911,17 @@ opt_absolute (void)
- nn.fledder (lea);
- nn.mark_def (regno);
- infos.insert (infos.begin () + i, nn);
-- while (i++ < j)
-- infos[i].mark_use (regno);
-- ++j;
+- pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
+- pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
++ /* SBF: unfortunately using the wrapped symbol without MEM does not work.
++ * The pic_ref reference gets decomposed and leads to no working code.
++ */
++ pic_ref = m68k_wrap_symbol (pic_ref, RELOC_GOT, m68k_get_gp (), reg);
+
-+ /* mark until last hit is found. */
-+ for (unsigned k = i + 1; k < infos.size (); ++k)
-+ {
-+ infos[k].mark_use (regno);
-+ if (k == *found.rbegin ())
-+ break;
++ /* SBF: adding const avoids decomposing. */
++ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
+ }
- ++change_count;
-+ --i;
- }
--
-- i = j;
++ else
++ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
++ }
++#endif
}
+ else if (GET_CODE (orig) == CONST)
+ {
+@@ -2463,7 +2572,8 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
+ orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
+ base == reg ? 0 : reg);
- if (change_count)
-
-From 6e6ca44d77a0ac430aaa9d55181fada079ad76d1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 4 May 2017 14:59:26 +0200
-Subject: [PATCH 110/303] @B fix cmp_sub
-
----
- gcc/bbb-opts.c | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index a4bb1e0a97a3..568ce2a6543d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2192,14 +2192,17 @@ opt_const_cmp_to_sub (void)
-
- rtx jmppattern = PATTERN (patchme);
+- if (GET_CODE (orig) == CONST_INT)
++ /* SBF: use normal plus and rely on optimizer with baserel(32). */
++ if (flag_pic < 3 && GET_CODE (orig) == CONST_INT)
+ pic_ref = plus_constant (Pmode, base, INTVAL (orig));
+ else
+ pic_ref = gen_rtx_PLUS (Pmode, base, orig);
+@@ -2787,7 +2897,10 @@ const_int_cost (HOST_WIDE_INT i)
+ }
+ }
-- rtx jmpsrc = XEXP(jmppattern, 1);
-- if (!jmpsrc)
-+ if (GET_RTX_LENGTH (GET_CODE(jmppattern)) < 2)
- ok = false;
-- else if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-+ else
- {
-- rtx condition = XEXP(jmpsrc, 0);
-- RTX_CODE code = GET_CODE(condition);
-- ok = code == EQ || code == NE;
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-+ {
-+ rtx condition = XEXP(jmpsrc, 0);
-+ RTX_CODE code = GET_CODE(condition);
-+ ok = code == EQ || code == NE;
-+ }
- }
- }
+-static bool
++#ifndef TARGET_AMIGA
++static
++#endif
++bool
+ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
+ int opno ATTRIBUTE_UNUSED,
+ int *total, bool speed ATTRIBUTE_UNUSED)
+@@ -2863,6 +2976,7 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
+ *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);
+ return true;
}
-
-From bcacd054f6a8b47c7fa16580697a23fc0cd3393b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 4 May 2017 22:59:56 +0200
-Subject: [PATCH 111/303] @R opt_cmp_sub is now capable to replace a chain of
- compares
-
----
- .cproject | 4 +
- gcc/bbb-opts.c | 243 +++++++++++++++++++++++++++++++++------------------------
- 2 files changed, 145 insertions(+), 102 deletions(-)
-
-diff --git a/.cproject b/.cproject
-index b3cddaefb27b..6db4cbe2447e 100755
---- .cproject
-+++ .cproject
-@@ -43,6 +43,7 @@
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
- <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin"/>
- </tool>
-@@ -58,6 +59,7 @@
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
- <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313" superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
- </tool>
-@@ -106,6 +108,7 @@
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
- <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1150724656" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
- </tool>
-@@ -119,6 +122,7 @@
- <listOptionValue builtIn="false" value="IN_GCC=1"/>
- <listOptionValue builtIn="false" value="HAVE_cc0=1"/>
- <listOptionValue builtIn="false" value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false" value="TARGET_AMIGA=1"/>
- </option>
- <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
- </tool>
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 568ce2a6543d..0d8ecedc7941 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -183,6 +183,18 @@ class insn_info
- void
- absolute2base (unsigned regno, unsigned base, rtx with_symbol);
-
-+ inline bool
-+ is_compare () const
-+ {
-+ return compare;
-+ }
-+
-+ inline machine_mode
-+ get_mode () const
-+ {
-+ return mode;
-+ }
-+
- inline bool
- is_dst_reg () const
- {
-@@ -387,6 +399,29 @@ class insn_info
- hard = 0;
- }
-
-+ inline void
-+ reset_flags ()
-+ {
-+ compare = false;
-+ dst_mem = false;
-+ src_mem = false;
-+ dst_plus = false;
-+ src_plus = false;
-+ src_const = false;
-+
-+ mode = VOIDmode;
-+
-+ dst_reg = 0;
-+ dst_mem_reg = 0;
-+ dst_symbol = 0;
-+ src_reg = 0;
-+ src_mem_reg = 0;
-+ src_symbol = 0;
-+ dst_mem_addr = 0;
-+
-+ src_mem_addr = 0;
-+ }
+
- inline bool
- is_empty ()
- {
-@@ -711,8 +746,6 @@ insn_info::fledder (rtx set)
- rtx dst = SET_DEST(set);
- rtx src = SET_SRC(set);
+ return false;
-- mode = GET_MODE(dst);
--
- if (dst == cc0_rtx)
- {
- compare = true;
-@@ -721,6 +754,8 @@ insn_info::fledder (rtx set)
- src = SET_SRC(set);
- }
+ case ASHIFT:
+@@ -2931,6 +3045,25 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
+ *total = 0;
+ return false;
-+ mode = GET_MODE(dst);
-+
- if (REG_P(dst))
- {
- dst_reg = dst;
-@@ -991,6 +1026,9 @@ void
- insn_info::set_insn (rtx_insn * newinsn)
- {
- insn = newinsn;
++ case MEM:
++ {
++ /* simple but not exact */
++ rtx y = XEXP(x, 0);
++ int yc = GET_CODE(y);
++ if (yc == REG || yc == PRE_INC || yc == POST_INC || yc == POST_DEC)
++ *total += 4;
++ else
++ if (yc == PRE_DEC)
++ *total += 6;
++ else
++ *total += 8;
+
-+ reset_flags ();
++ if (mode != QImode && mode != QImode)
++ *total += 4;
+
- fledder (PATTERN (insn));
- }
-
-@@ -1255,7 +1293,7 @@ update_insn_infos (void)
-
- /* fill the mask of general used regs. */
- insn_info zz;
-- for (int i = 0; i < infos.size (); ++i)
-+ for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & ii = infos[i];
- if (ii.in_proepi () != 1)
-@@ -2097,140 +2135,141 @@ opt_const_cmp_to_sub (void)
- {
- unsigned change_count = 0;
- #if HAVE_cc0
-- for (int index = infos.size () - 2; index > 0; --index)
-+ if (infos.size () < 2)
-+ return change_count;
++ return true;
++ }
+
-+ unsigned lastsub = 0;
-+ for (unsigned index = infos.size () - 2; index > 0; --index)
+ default:
+ return false;
+ }
+@@ -4456,7 +4589,9 @@ print_operand (FILE *file, rtx op, int letter)
+ else if (letter == 'p')
{
-- rtx_insn * insn = infos[index].get_insn ();
-- rtx seti = single_set (insn);
-- if (!seti)
-+ insn_info & i1 = infos[index];
-+
-+ /* we wan't a compare or tst insn, */
-+ if (!i1.is_compare ())
- continue;
-
-- rtx dsti = SET_DEST(seti);
-- if (dsti != cc0_rtx)
-+ if (GET_MODE_SIZE(i1.get_mode()) > 4 || !i1.is_dst_reg () || REGNO(i1.get_dst_reg()) > 7)
- continue;
-
-- rtx srci = SET_SRC(seti);
-- if (GET_CODE(srci) != COMPARE)
-+ /* src must be a reg dead register with a constant - or a #0 */
-+ if (!i1.get_src_reg () && (!i1.is_src_const () || i1.is_src_plus ()))
- continue;
-
-- rtx left = XEXP(srci, 0);
-- rtx right = XEXP(srci, 1);
-- if (!REG_P(left) || !REG_P(right) || REG_NREGS(left) > 1 || REG_NREGS(right) > 1)
-+ /* allow an alive reg, if life ends at previous handled sub. */
-+ int lastsubval = 0;
-+ if (lastsub == index + 3)
-+ {
-+ insn_info & pp = infos[lastsub];
-+ if (pp.get_dst_regno () != i1.get_dst_regno ())
-+ continue;
-+ lastsubval = pp.get_src_intval ();
-+ }
-+ else if (!is_reg_dead (i1.get_dst_regno (), index))
- continue;
-
-- // TODO
-- // FEATURE: check if the next uses are also a add/sub
-- // then maybe that add/sub can be adjusted too
-+ insn_info & i0 = infos[index - 1];
-+ int intval = 0;
-+ /* compare with register - check previous insn for load with constant. */
-+ if (i1.is_src_reg ())
-+ {
-+ if (!is_reg_dead (i1.get_src_regno (), index))
-+ continue;
-
--// if (!find_reg_note (insn, REG_DEAD, left) || !find_reg_note (insn, REG_DEAD, right))
--// continue;
-- /* use own reg_dead - reg_notes seem to be inaccurate!? */
-- if (!is_reg_dead (REGNO(left), index) || !is_reg_dead (REGNO(right), index))
-- continue;
-+ if (GET_MODE_SIZE(i0.get_mode()) > 4)
-+ continue;
-
-- // maybe add a search?
-- rtx_insn * prev = infos[index - 1].get_insn ();
-- rtx setp = single_set (prev);
-- if (!setp)
-- continue;
-+ if (!i0.is_dst_reg () && (!i0.is_src_const () || i0.is_src_plus ()))
-+ continue;
-
-- rtx constant_reg = SET_DEST(setp);
-- if (!REG_P(constant_reg))
-- continue;
-+ if (i0.get_dst_regno () != i1.get_src_regno ())
-+ continue;
-
-- rtx srcp = SET_SRC(setp);
-- if (!CONST_INT_P(srcp))
-- continue;
-+ intval = -i0.get_src_intval ();
-+ if (intval < -8 || intval > 7)
-+ continue;
-
-- int intval = -INTVAL(srcp);
-- if (intval < -8 || intval > 7 || intval == 0)
-- continue;
-+ /* is the next sub value in range? */
-+ if (lastsub == index + 3 && (lastsubval - intval < -8 || lastsubval - intval > 7))
-+ continue;
-+ }
-
-- enum machine_mode mode = GET_MODE(constant_reg);
-- if (GET_MODE_SIZE(mode) > 4)
-+ /* next insn must be the jump. */
-+ insn_info & i2 = infos[index + 1];
-+ if (!i2.is_jump ())
- continue;
-
-- // printf("mode size: %d\n", GET_MODE_SIZE(mode));
-+ rtx_insn * jump = i2.get_insn ();
-+ rtx jmppattern = PATTERN (jump);
-+ if (GET_RTX_LENGTH (GET_CODE(jmppattern)) < 2)
-+ continue;
-
-- rtx reg = constant_reg == left ? right : constant_reg == right ? left : 0;
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) != IF_THEN_ELSE)
-+ continue;
-
-- // no gain with address regs.
-- if (!reg || REGNO(reg) > 7)
-+ rtx condition = XEXP(jmpsrc, 0);
-+ RTX_CODE code = GET_CODE(condition);
-+ if (code != EQ && code != NE)
- continue;
-
-- // search the jump(s)
-- bool ok = true;
-+ if (intval)
- {
-- // invert all conditions using this statement.
-- std::vector<unsigned> todo;
-- std::vector<unsigned> done;
-- done.resize (infos.size ());
-- todo.push_back (index + 1);
-+ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
-+ /* create the sub statement. */
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), intval));
-
-- while (ok && todo.size ())
-- {
-- unsigned pos = todo[todo.size () - 1];
-- todo.pop_back ();
-+ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub));
-
-- if (done[pos])
-- continue;
-+ int num_clobbers_to_add = 0;
-+ int insn_code_number = recog (PATTERN (subinsn), subinsn, &num_clobbers_to_add);
-+ if (insn_code_number < 0 || !check_asm_operands (PATTERN (subinsn)))
-+ continue;
-
-- done[pos] = 1;
-+ /* delete move #x,dy. */
-+ SET_INSN_DELETED(i0.get_insn ())
-+ /* delete cmp dx,dy */
-+ SET_INSN_DELETED(i1.get_insn ());
-+ /* add a cmp #0 - to be removed in final() */
-
-- if (infos[pos].is_def (FIRST_PSEUDO_REGISTER))
-- continue;
-+ /* convert cmp/tst into sub */
-+ subinsn = emit_insn_before (PATTERN (subinsn), i1.get_insn ());
-+ i1.set_insn (subinsn);
-
-- if (pos + 1 < infos.size ())
-- todo.push_back (pos + 1);
-+ rtx neu = gen_rtx_SET(cc0_rtx,
-+ gen_rtx_COMPARE(i1.get_mode (), copyreg, gen_rtx_CONST_INT(i1.get_mode (), 0)));
-
-- rtx_insn * patchme = infos[pos].get_insn ();
-- if (!JUMP_P(patchme))
-- continue;
-+ emit_insn_before (neu, i2.get_insn ());
-
-- auto j = insn2index.find ((rtx_insn *) JUMP_LABEL(patchme));
-- if (j != insn2index.end ())
-- todo.push_back (j->second->get_index ());
-+ log ("const_cmp_to_sub replaced %s == %s (%d) with sub %d,%s\n", reg_names[i1.get_dst_regno ()],
-+ reg_names[i0.get_dst_regno ()],
-+ -intval, -intval, reg_names[i1.get_dst_regno ()]);
-
-- rtx jmppattern = PATTERN (patchme);
-+ if (index + 3 == lastsub)
-+ {
-+ /* patch previous sub - or even a compare. */
-+ insn_info & pp = infos[lastsub];
-+
-+ int diff = lastsubval - intval;
-+ rtx c = gen_rtx_CONST_INT (i1.get_mode (), diff);
-
-- if (GET_RTX_LENGTH (GET_CODE(jmppattern)) < 2)
-- ok = false;
-+ if (pp.is_compare ())
-+ {
-+ /* still a compare with 0 -> insert the sub. */
-+ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
-+ /* create the sub statement. */
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, c);
-+ rtx set = gen_rtx_SET(copyreg, sub);
-+ emit_insn_before (set, pp.get_insn ());
-+ }
- else
- {
-- rtx jmpsrc = XEXP(jmppattern, 1);
-- if (GET_CODE(jmpsrc) == IF_THEN_ELSE)
-- {
-- rtx condition = XEXP(jmpsrc, 0);
-- RTX_CODE code = GET_CODE(condition);
-- ok = code == EQ || code == NE;
-- }
-+ /* modify the sub. */
-+ XEXP(SET_SRC(PATTERN(pp.get_insn())), 1) = c;
- }
- }
-- }
-- if (!ok)
-- continue;
--
-- rtx plus = gen_rtx_PLUS(mode, copy_reg (reg, -1), gen_rtx_CONST_INT (mode, intval));
-
-- rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(copy_reg (reg, -1), plus));
--
-- int num_clobbers_to_add = 0;
-- int insn_code_number = recog (PATTERN (neuprev), neuprev, &num_clobbers_to_add);
-- if (insn_code_number < 0 || !check_asm_operands (PATTERN (neuprev)))
-- continue;
--
-- // also convert current statement to cmp #0, reg
-- SET_INSN_DELETED(insn);
-- rtx copyreg = copy_reg (reg, -1);
-- rtx neu = gen_rtx_SET(cc0_rtx, gen_rtx_COMPARE(mode, copyreg, gen_rtx_CONST_INT(mode, 0)));
-- insn = emit_insn_after (neu, prev);
-- add_reg_note (insn, REG_DEAD, copyreg);
--
-- SET_INSN_DELETED(prev);
-- prev = emit_insn_before (PATTERN (neuprev), insn);
--
-- log ("const_cmp_to_sub replaced reg-reg compare with sub\n");
--
-- ++change_count;
-+ lastsub = index;
-+ ++change_count;
-+ }
+ output_addr_const (file, op);
+- if (!(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
++ /* SBF: do not add @PLTPC with baserel(32). */
++ if (flag_pic < 3
++ && !(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
+ fprintf (file, "@PLTPC");
}
- #endif
- return change_count;
-@@ -2992,7 +3031,7 @@ namespace
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
- be_very_verbose = strchr (string_bbb_opts, 'V');
-- be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v') || 1;
-+ be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v');
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-
-From 92278608b8be02dd6fc699e0ea912e12e3047a23 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 7 May 2017 17:50:45 +0200
-Subject: [PATCH 112/303] @B opt_absolute now only touches insns with a valid
- mode.
-
----
- gcc/bbb-opts.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 0d8ecedc7941..e6ff270e8837 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -755,6 +755,8 @@ insn_info::fledder (rtx set)
+ else if (GET_CODE (op) == REG)
+@@ -4475,34 +4610,52 @@ print_operand (FILE *file, rtx op, int letter)
+ && CONSTANT_ADDRESS_P (XEXP (op, 0))
+ && !(GET_CODE (XEXP (op, 0)) == CONST_INT
+ && INTVAL (XEXP (op, 0)) < 0x8000
+- && INTVAL (XEXP (op, 0)) >= -0x8000))
+- fprintf (file, MOTOROLA ? ".l" : ":l");
++ && INTVAL (XEXP (op, 0)) >= -0x8000)
++#ifdef TARGET_AMIGA
++/* SBF: Do not append some 'l' with baserel(32). */
++ && !amiga_is_const_pic_ref(XEXP(op, 0))
++#endif
++ )
++ fprintf (file, MOTOROLA ? ".l" : ":l");
}
-
- mode = GET_MODE(dst);
-+ if (mode == VOIDmode)
-+ mode = GET_MODE(src);
-
- if (REG_P(dst))
- {
-@@ -1038,7 +1040,6 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- rtx set = PATTERN (get_insn ());
- rtx src = SET_SRC(set);
- rtx dst = SET_DEST(set);
-- machine_mode mode = GET_MODE(dst);
-
- rtx pattern;
- rtx reg = gen_raw_REG (SImode, regno);
-@@ -2839,6 +2840,9 @@ opt_absolute (void)
- if (!is_dst && !is_src)
- continue;
-
-+ if (ii.get_mode() == VOIDmode)
-+ continue;
-+
- unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00 & usable_regs;
- if (!freemask)
- continue;
-@@ -2860,6 +2864,9 @@ opt_absolute (void)
- if (!freemask)
- break;
-
-+ if (jj.get_mode() == VOIDmode)
-+ continue;
-+
- bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ()) && !jj.has_dst_memreg ()
- && jj.get_dst_symbol () == with_symbol;
- bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ()) && !jj.has_src_memreg ()
-
-From 1e4de684a62e18bcb9655cbc1029c24dd426fcb5 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 9 May 2017 19:40:17 +0200
-Subject: [PATCH 113/303] @R be more compatible to different gcc versions
-
-replaced auto with explicite types
----
- gcc/bbb-opts.c | 21 ++++++++++++---------
- 1 file changed, 12 insertions(+), 9 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 0d8ecedc7941..c1e3f247335f 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -923,6 +923,9 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- static std::vector<insn_info> infos;
- static std::vector<rtx_insn *> jumps;
- static std::map<rtx_insn *, insn_info *> insn2index;
-+typedef std::vector<insn_info>::iterator insn_info_iterator;
-+typedef std::vector<rtx_insn *>::iterator rtx_insn_iterator;
-+typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
-
- static insn_info * info0;
- static unsigned usable_regs;
-@@ -1130,7 +1133,7 @@ void
- append_reg_usage (FILE * f, rtx_insn * insn)
- {
-
-- auto i = insn2index.find (insn);
-+ i2i_iterator i = insn2index.find (insn);
- if (i == insn2index.end ())
- return;
-
-@@ -1238,11 +1241,11 @@ update_insn_infos (void)
- if (LABEL_P(insn))
- {
- /* work on all jumps referring to that label. */
-- for (auto i = jumps.begin (); i != jumps.end (); ++i)
-+ for (rtx_insn_iterator i = jumps.begin (); i != jumps.end (); ++i)
- {
- if (JUMP_LABEL(*i) == insn)
- {
-- auto j = insn2index.find (*i);
-+ i2i_iterator j = insn2index.find (*i);
- if (j != insn2index.end ())
- todo.push_back (std::make_pair (j->second->get_index (), ii));
- }
-@@ -1481,11 +1484,11 @@ opt_reg_rename (void)
- * check if the reg was used at that jump.
- * if used, find def
- */
-- for (auto i = jumps.begin (); i != jumps.end (); ++i)
-+ for (rtx_insn_iterator i = jumps.begin (); i != jumps.end (); ++i)
- {
- if (JUMP_LABEL(*i) == insn)
- {
-- auto j = insn2index.find (*i);
-+ i2i_iterator j = insn2index.find (*i);
- if (j == insn2index.end ())
- continue;
-
-@@ -1528,7 +1531,7 @@ opt_reg_rename (void)
- /* follow jump and/or next insn. */
- if (JUMP_P(insn))
- {
-- auto j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-+ i2i_iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
- if (j == insn2index.end ())
- {
- /* whoops - label not found. */
-@@ -2797,7 +2800,7 @@ opt_shrink_stack_frame (void)
- if (freemask & (1 << FRAME_POINTER_REGNUM))
- {
- log ("dropping unused frame pointer\n");
-- for (auto i = a5pos.rbegin (); i != a5pos.rend (); ++i)
-+ for (std::vector<int>::reverse_iterator i = a5pos.rbegin (); i != a5pos.rend (); ++i)
- {
- SET_INSN_DELETED(infos[*i].get_insn ());
- infos.erase (infos.begin () + *i);
-@@ -2909,7 +2912,7 @@ opt_absolute (void)
- if (freemask && found.size () > 2)
- {
- /* check again. */
-- for (auto k = found.begin (); k != found.end ();)
-+ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();)
- {
- insn_info & kk = infos[*k];
- if (kk.get_dst_addr () - base > 0x7ffc)
-@@ -2926,7 +2929,7 @@ opt_absolute (void)
- else
- log ("modifying %d absolute addresses using %s\n", found.size (), reg_names[regno]);
-
-- for (auto k = found.begin (); k != found.end (); ++k)
-+ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end (); ++k)
- {
- insn_info & kk = infos[*k];
- kk.absolute2base (regno, base, with_symbol);
-
-From 3625786a260599ad20349b8bd22cc88ad90fecb0 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 12 May 2017 22:17:41 +0200
-Subject: [PATCH 114/303] @I remove eclipse specific defines
-
----
- gcc/bbb-opts.c | 9 ---------
- 1 file changed, 9 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index c1e3f247335f..77e7f71f3b47 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -74,15 +74,6 @@
- bool be_very_verbose;
- bool be_verbose;
-
--#ifdef __ECLIPSE__
--//extern char * string_bbb_opts;
--#define FIRST_PSEUDO_REGISTER 25
--#define FRAME_POINTER_REGNUM 13
--#define STACK_POINTER_REGNUM 15
--#define NOTICE_UPDATE_CC(a,b)
--#define Pmode SImode
--#define PIC_REG 12
--#endif
- extern struct lang_hooks lang_hooks;
-
- /* Lookup of the current function name. */
-
-From e43aec51a54659db8760159c651a27b4efb88580 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 13 May 2017 23:06:49 +0200
-Subject: [PATCH 115/303] @B avoid lea into data regs - enforce constraints
-
----
- gcc/config/m68k/constraints.md | 6 ++++++
- gcc/config/m68k/m68k.md | 8 ++++----
- 2 files changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/config/m68k/constraints.md b/gcc/config/m68k/constraints.md
-index b62120895304..94a785dc95b6 100644
---- gcc/config/m68k/constraints.md
-+++ gcc/config/m68k/constraints.md
-@@ -97,6 +97,12 @@
- (match_test "!TARGET_PCREL")
- (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
-
-+(define_constraint "t"
-+ "Used for operands that satisfy 's' without PIC stuff, when -mpcrel is not in effect."
-+ (and (match_code "symbol_ref,label_ref,const")
-+ (match_test "!TARGET_PCREL")
-+ (match_test "!flag_pic || GET_CODE(op) != CONST || GET_CODE (XEXP (op, 0)) == SYMBOL_REF || GET_CODE (XEXP (op, 0)) == LABEL_REF")))
-+
- (define_memory_constraint "Q"
- "Means address register indirect addressing mode."
- (and (match_code "mem")
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index 24332476b91b..d5ab0cfab8c8 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -955,8 +955,8 @@
- (define_insn "*movsi_m68k"
- ;; Notes: make sure no alternative allows g vs g.
- ;; We don't allow f-regs since fixed point cannot go in them.
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
-- (match_operand:SI 1 "general_src_operand" "damSnT,n,i"))]
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g,a,d,a<")
-+ (match_operand:SI 1 "general_src_operand" "damSnt,T,n,i"))]
- "!TARGET_COLDFIRE && reload_completed"
- {
- return output_move_simode (operands);
-@@ -966,8 +966,8 @@
- ;; force integer constants in range for a moveq to be reloaded
- ;; if they are headed for memory.
- (define_insn "*movsi_m68k2"
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
-- (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))]
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g,a,d,a<")
-+ (match_operand:SI 1 "general_src_operand" "damSKt,T,n,i"))]
-
- "!TARGET_COLDFIRE"
- {
-
-From 4a3f28381185450e2ceeafa657032690420a66ab Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 13 May 2017 23:07:46 +0200
-Subject: [PATCH 116/303] @B use fresh insns instead of modifying old ones in
- opt_strcpy()
-
----
- gcc/bbb-opts.c | 16 ++++------------
- 1 file changed, 4 insertions(+), 12 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index e6ff270e8837..f4dfb6177260 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1963,8 +1963,8 @@ opt_strcpy ()
- int num_clobbers_to_add = 0;
- int insn_code_number;
-
-- rtx_insn * newinsn = make_insn_raw (
-- gen_rtx_SET(SET_DEST(single_set(reg2x)), SET_SRC(single_set (x2reg))));
-+ rtx pattern = gen_rtx_SET(SET_DEST(single_set(reg2x)), SET_SRC(single_set (x2reg)));
-+ rtx_insn * newinsn = make_insn_raw (pattern);
- insn_code_number = recog (PATTERN (newinsn), newinsn, &num_clobbers_to_add);
- if (insn_code_number >= 0 && check_asm_operands (PATTERN (newinsn)))
- {
-@@ -1973,18 +1973,10 @@ opt_strcpy ()
- log ("opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
- reg_names[REGNO(dst)]);
-
-- SET_SRC(single_set(reg2x)) = SET_SRC(single_set (x2reg));
--
-- for (link = REG_NOTES(x2reg); link; link = XEXP(link, 1))
-- if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
-- {
-- if (GET_CODE (link) == EXPR_LIST)
-- add_reg_note (reg2x, REG_NOTE_KIND(link), copy_insn_1 (XEXP(link, 0)));
-- else
-- add_shallow_copy_of_reg_note (reg2x, link);
-- }
-+ emit_insn_after(pattern, reg2x);
-
- SET_INSN_DELETED(x2reg);
-+ SET_INSN_DELETED(reg2x);
- SET_INSN_DELETED(insn);
-
- ++change_count;
-
-From 03bac6a165016f2c667087d2f5102d2bc2cb897c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 13 May 2017 23:34:25 +0200
-Subject: [PATCH 117/303] @B exclude some operations and compares in
- opt_absolute()
-
----
- gcc/bbb-opts.c | 22 +++++++++++++++++++++-
- 1 file changed, 21 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f4dfb6177260..ff7532281630 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2826,6 +2826,9 @@ opt_absolute (void)
+ else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
{
- insn_info & ii = infos[i];
-
-+ if (ii.is_compare())
-+ continue;
-+
- bool is_dst = ii.is_dst_mem () && (ii.has_dst_addr () || ii.get_dst_symbol ()) && !ii.has_dst_memreg ();
- bool is_src = ii.is_src_mem () && (ii.has_src_addr () || ii.get_src_symbol ()) && !ii.has_src_memreg ();
-
-@@ -2839,6 +2842,14 @@ opt_absolute (void)
- if (!freemask)
- continue;
-
-+ rtx pattern = PATTERN(ii.get_insn());
-+ if (is_dst && !ii.get_src_reg() && !ii.is_src_const())
-+ if (MEM_P(XEXP(XEXP(pattern, 1), 0)))
-+ continue;
-+ if (is_src && !ii.get_dst_reg())
-+ if (MEM_P(XEXP(XEXP(pattern, 0), 0)))
-+ continue;
-+
- rtx with_symbol = is_dst ? ii.get_dst_symbol () : ii.get_src_symbol ();
-
- std::vector<unsigned> found;
-@@ -2856,13 +2867,22 @@ opt_absolute (void)
- if (!freemask)
- break;
-
-- if (jj.get_mode() == VOIDmode)
-+ if (jj.get_mode() == VOIDmode || jj.is_compare())
- continue;
-
- bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ()) && !jj.has_dst_memreg ()
- && jj.get_dst_symbol () == with_symbol;
- bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ()) && !jj.has_src_memreg ()
- && jj.get_src_symbol () == with_symbol;
-+
-+ pattern = PATTERN(jj.get_insn());
-+ if (j_dst && !jj.get_src_reg() && !jj.is_src_const())
-+ if (MEM_P(XEXP(XEXP(pattern, 1), 0)))
-+ continue;
-+ if (j_src && !jj.get_dst_reg())
-+ if (MEM_P(XEXP(XEXP(pattern, 0), 0)))
-+ continue;
-+
- if (j_dst)
- {
- unsigned addr = jj.get_dst_addr ();
-
-From 9e1dd52e9e1bdb1ca9af945c5853b9d5b3a9fb46 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 15 May 2017 11:06:25 +0200
-Subject: [PATCH 118/303] @B fix #20: handle subrge/strict_low_part in (b)
-
----
- gcc/DATESTAMP | 2 +-
- gcc/bbb-opts.c | 103 +++++++++++++++++++++++++++++++--------------------------
- 2 files changed, 58 insertions(+), 47 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 59aff9a1ff47..2f2212531db5 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170430
-+20170515
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index ff7532281630..ebae14f41832 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -148,6 +148,7 @@ class insn_info
- bool src_mem;
- bool dst_plus;
- bool src_plus;
-+ int src_op;
- bool src_const;
-
- machine_mode mode;
-@@ -165,7 +166,7 @@ class insn_info
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
-- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_const (
-+ false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (0), src_const (
- false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (
- 0), dst_mem_addr (0), src_mem_addr (0)
- {
-@@ -281,13 +282,13 @@ class insn_info
- inline bool
- is_src_reg () const
- {
-- return src_reg && !src_plus;
-+ return src_reg && !src_op;
- }
-
-- inline bool
-- is_src_plus () const
-+ inline int
-+ get_src_op () const
- {
-- return src_reg && src_plus;
-+ return src_op;
- }
-
- inline bool
-@@ -407,6 +408,7 @@ class insn_info
- src_mem = false;
- dst_plus = false;
- src_plus = false;
-+ src_op = 0;
- src_const = false;
-
- mode = VOIDmode;
-@@ -754,6 +756,9 @@ insn_info::fledder (rtx set)
- src = SET_SRC(set);
+ long l;
+ REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
++#ifndef TARGET_AMIGAOS_VASM
+ asm_fprintf (file, "%I0x%lx", l & 0xFFFFFFFF);
++#else
++ asm_fprintf (file, "%I$%lx", l & 0xFFFFFFFF);
++#endif
}
-
-+ if (GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG)
-+ dst = XEXP(dst, 0);
-+
- mode = GET_MODE(dst);
- if (mode == VOIDmode)
- mode = GET_MODE(src);
-@@ -845,22 +850,26 @@ insn_info::fledder (rtx set)
- src_const = true;
- src_mem_addr = INTVAL(src);
+ else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
+ {
+ long l[3];
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
++#ifndef TARGET_AMIGAOS_VASM
+ asm_fprintf (file, "%I0x%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
+ l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
++#else
++ asm_fprintf (file, "%I$%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
++ l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
++#endif
}
-- else if (GET_CODE(src) == PLUS)
-+ /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */
-+ if (*GET_RTX_FORMAT(GET_CODE(src)) == 'e')
+ else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
{
-- src_plus = true;
-+ src_op = GET_CODE(src);
- rtx reg = XEXP(src, 0);
-- rtx konst = XEXP(src, 1);
-- if (REG_P(reg))
-+ if (REG_P(reg) && GET_RTX_LENGTH(GET_CODE(src)) >= 2)
- {
-- if (GET_CODE(konst) == CONST_INT)
-+ rtx konst = XEXP(src, 1);
-+ src_reg = reg;
-+ if (konst)
- {
-- src_reg = reg;
-- src_const = true;
-- src_mem_addr = INTVAL(konst);
-- }
-- else if (REG_P(konst))
-- {
-- src_reg = konst;
-+ if (GET_CODE(konst) == CONST_INT)
-+ {
-+ src_const = true;
-+ src_mem_addr = INTVAL(konst);
-+ }
-+ else if (REG_P(konst))
-+ {
-+ src_reg = konst; /* dst_reg = dst_reg OP src_reg: store src_reg not dst_reg */
-+ }
- }
- }
+ long l[2];
+ REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
++#ifndef TARGET_AMIGAOS_VASM
+ asm_fprintf (file, "%I0x%lx%08lx", l[0] & 0xFFFFFFFF, l[1] & 0xFFFFFFFF);
++#else
++ asm_fprintf (file, "%I$%lx%08lx", l[0] & 0xFFFFFFFF, l[1] & 0xFFFFFFFF);
++#endif
}
-@@ -969,7 +978,7 @@ void
- insn_info::plus_to_move (rtx_insn * newinsn)
- {
- insn = newinsn;
-- src_plus = false;
-+ src_op = 0;
- src_reg = XEXP(PATTERN (newinsn), 1);
- insn2index.insert (std::make_pair (insn, this));
- // usage flags did not change
-@@ -1603,7 +1612,7 @@ opt_reg_rename (void)
- if (!ok)
- continue;
-
-- log ("opt_reg_rename %s -> %s (%d locs, start at %d)\n", reg_names[oldregno], reg_names[newregno],
-+ log ("(r) opt_reg_rename %s -> %s (%d locs, start at %d)\n", reg_names[oldregno], reg_names[newregno],
- patch.size (), index);
-
- /* apply all changes. */
-@@ -1846,7 +1855,7 @@ opt_propagate_moves ()
- rtx_insn * after = infos[index + 1].get_insn ();
- rtx bset = single_set (before);
-
-- log ("propagate_moves condition met, moving regs %s, %s\n",
-+ log ("(p) propagate_moves condition met, moving regs %s, %s\n",
- reg_names[REGNO(srci)],
- reg_names[REGNO(dsti)]);
-
-@@ -1882,7 +1891,7 @@ opt_propagate_moves ()
- /* add fixes if there were jumps out of the loop. */
- if (jump_out.size ())
- {
-- log ("propagate_moves fixing %d jump outs\n", jump_out.size ());
-+ log ("(p) propagate_moves fixing %d jump outs\n", jump_out.size ());
-
- for (unsigned k = 0; k < jump_out.size (); ++k)
- {
-@@ -1970,10 +1979,10 @@ opt_strcpy ()
- {
- rtx link;
-
-- log ("opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
-+ log ("(s) opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
- reg_names[REGNO(dst)]);
-
-- emit_insn_after(pattern, reg2x);
-+ emit_insn_after (pattern, reg2x);
-
- SET_INSN_DELETED(x2reg);
- SET_INSN_DELETED(reg2x);
-@@ -2086,7 +2095,7 @@ opt_commute_add_move (void)
-
- if (validate_change (next, &SET_DEST(set2), newmem, 0))
- {
-- log ("commute_add_move found\n");
-+ log ("(a) commute_add_move found\n");
-
- SET_INSN_DELETED(insn);
-
-@@ -2144,7 +2153,7 @@ opt_const_cmp_to_sub (void)
- continue;
-
- /* src must be a reg dead register with a constant - or a #0 */
-- if (!i1.get_src_reg () && (!i1.is_src_const () || i1.is_src_plus ()))
-+ if (!i1.get_src_reg () && (!i1.is_src_const () || i1.get_src_op () == PLUS))
- continue;
-
- /* allow an alive reg, if life ends at previous handled sub. */
-@@ -2170,7 +2179,7 @@ opt_const_cmp_to_sub (void)
- if (GET_MODE_SIZE(i0.get_mode()) > 4)
- continue;
-
-- if (!i0.is_dst_reg () && (!i0.is_src_const () || i0.is_src_plus ()))
-+ if (!i0.is_dst_reg () && (!i0.is_src_const () || i0.get_src_op () == PLUS))
- continue;
-
- if (i0.get_dst_regno () != i1.get_src_regno ())
-@@ -2232,7 +2241,7 @@ opt_const_cmp_to_sub (void)
-
- emit_insn_before (neu, i2.get_insn ());
-
-- log ("const_cmp_to_sub replaced %s == %s (%d) with sub %d,%s\n", reg_names[i1.get_dst_regno ()],
-+ log ("(c) const_cmp_to_sub replaced %s == %s (%d) with sub %d,%s\n", reg_names[i1.get_dst_regno ()],
- reg_names[i0.get_dst_regno ()],
- -intval, -intval, reg_names[i1.get_dst_regno ()]);
-
-@@ -2293,7 +2302,7 @@ opt_elim_dead_assign (void)
-
- if (is_reg_dead (REGNO(dst), index))
- {
-- log ("%d: elim_dead_assign to %s\n", index, reg_names[REGNO(dst)]);
-+ log ("(e) %d: elim_dead_assign to %s\n", index, reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
- ++change_count;
- }
-@@ -2333,7 +2342,7 @@ opt_merge_add (void)
- continue;
- }
-
-- if (!ii0.is_dst_reg () || !ii0.is_src_plus () || !ii1.is_src_plus () || !ii2.is_src_plus ())
-+ if (!ii0.is_dst_reg () || ii0.get_src_op () != PLUS || ii1.get_src_op () != PLUS || ii2.get_src_op () != PLUS)
- continue;
-
- if (!ii0.is_src_const () || !ii2.is_src_const () || ii0.get_src_intval () != ii2.get_src_intval ())
-@@ -2349,7 +2358,7 @@ opt_merge_add (void)
- if (cc_status.value1 || cc_status.value2)
- continue;
-
-- log ("%d: merge_add applied\n", index);
-+ log ("(m) %d: merge_add applied\n", index);
-
- rtx_insn * insn0 = ii0.get_insn ();
- rtx set = PATTERN (insn0);
-@@ -2610,7 +2619,7 @@ opt_shrink_stack_frame (void)
- unsigned regbit = 1 << REGNO(reg);
- if (freemask & regbit)
- {
-- log (i < prologueend ? "remove push for %s\n" : "remove pop for %s\n",
-+ log (i < prologueend ? "(f) remove push for %s\n" : "(f) remove pop for %s\n",
- reg_names[REGNO(reg)]);
- if (i < prologueend)
- adjust += 4;
-@@ -2631,7 +2640,7 @@ opt_shrink_stack_frame (void)
- int add1 = i < prologueend || !usea5 ? 1 : 0;
- if ((int) regs.size () + add1 < XVECLEN(pattern, 0) || regs.size () <= 2)
- {
-- log ("shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1, regs.size ());
-+ log ("(f) shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1, regs.size ());
- if (regs.size () <= 2)
- {
- changed = 1;
-@@ -2726,7 +2735,7 @@ opt_shrink_stack_frame (void)
- if (freemask & regbit)
- {
- adjust += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
-- log ("remove push for %s\n", reg_names[REGNO(src)]);
-+ log ("(f) remove push for %s\n", reg_names[REGNO(src)]);
- SET_INSN_DELETED(insn);
- ++changed;
- }
-@@ -2738,7 +2747,7 @@ opt_shrink_stack_frame (void)
- unsigned regbit = 1 << REGNO(dst);
- if (freemask & regbit)
- {
-- log ("remove pop for %s\n", reg_names[REGNO(dst)]);
-+ log ("(f) remove pop for %s\n", reg_names[REGNO(dst)]);
- SET_INSN_DELETED(insn);
- ++changed;
- }
-@@ -2789,7 +2798,7 @@ opt_shrink_stack_frame (void)
- */
- if (freemask & (1 << FRAME_POINTER_REGNUM))
- {
-- log ("dropping unused frame pointer\n");
-+ log ("(f) dropping unused frame pointer\n");
- for (auto i = a5pos.rbegin (); i != a5pos.rend (); ++i)
- {
- SET_INSN_DELETED(infos[*i].get_insn ());
-@@ -2826,7 +2835,7 @@ opt_absolute (void)
+ else
{
- insn_info & ii = infos[i];
-
-- if (ii.is_compare())
-+ if (ii.is_compare ())
- continue;
-
- bool is_dst = ii.is_dst_mem () && (ii.has_dst_addr () || ii.get_dst_symbol ()) && !ii.has_dst_memreg ();
-@@ -2835,18 +2844,19 @@ opt_absolute (void)
- if (!is_dst && !is_src)
- continue;
-
-- if (ii.get_mode() == VOIDmode)
-+ if (ii.get_mode () == VOIDmode)
- continue;
-
- unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00 & usable_regs;
- if (!freemask)
- continue;
-
-- rtx pattern = PATTERN(ii.get_insn());
-- if (is_dst && !ii.get_src_reg() && !ii.is_src_const())
-+ /* exclude operations on that symbol. */
-+ rtx pattern = PATTERN (ii.get_insn ());
-+ if (is_dst && !ii.get_src_reg () && !ii.is_src_const ())
- if (MEM_P(XEXP(XEXP(pattern, 1), 0)))
- continue;
-- if (is_src && !ii.get_dst_reg())
-+ if (is_src && !ii.get_dst_reg ())
- if (MEM_P(XEXP(XEXP(pattern, 0), 0)))
- continue;
-
-@@ -2867,7 +2877,7 @@ opt_absolute (void)
- if (!freemask)
- break;
-
-- if (jj.get_mode() == VOIDmode || jj.is_compare())
-+ if (jj.get_mode () == VOIDmode || jj.is_compare ())
- continue;
-
- bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ()) && !jj.has_dst_memreg ()
-@@ -2875,11 +2885,12 @@ opt_absolute (void)
- bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ()) && !jj.has_src_memreg ()
- && jj.get_src_symbol () == with_symbol;
-
-- pattern = PATTERN(jj.get_insn());
-- if (j_dst && !jj.get_src_reg() && !jj.is_src_const())
-+ /* exclude operations on that symbol. */
-+ pattern = PATTERN (jj.get_insn ());
-+ if (j_dst && !jj.get_src_reg () && !jj.is_src_const ())
- if (MEM_P(XEXP(XEXP(pattern, 1), 0)))
- continue;
-- if (j_src && !jj.get_dst_reg())
-+ if (j_src && !jj.get_dst_reg ())
- if (MEM_P(XEXP(XEXP(pattern, 0), 0)))
- continue;
-
-@@ -2941,9 +2952,9 @@ opt_absolute (void)
+ /* Use `print_operand_address' instead of `output_addr_const'
+ to ensure that we print relevant PIC stuff. */
+ asm_fprintf (file, "%I");
+- if (TARGET_PCREL
++ if ((TARGET_PCREL || flag_pic > 2)
+ && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
+ print_operand_address (file, op);
+ else
+@@ -4521,7 +4674,19 @@ m68k_get_reloc_decoration (enum m68k_reloc reloc)
+ switch (reloc)
+ {
+ case RELOC_GOT:
+- if (MOTOROLA)
++ /* SBF: add the proper extension for baserel relocs with baserel(32). */
++ if (TARGET_AMIGA)
++ {
++ if (flag_pic == 1)
++ return ".w";
++ else if (flag_pic == 3)
++ return ":W";
++ else if (flag_pic == 4)
++ return ":L";
++ else
++ return "";
++ }
++ if (MOTOROLA)
{
- unsigned regno = bit2regno (freemask);
- if (with_symbol)
-- log ("modifying %d symbol addresses using %s\n", found.size (), reg_names[regno]);
-+ log ("(b) modifying %d symbol addresses using %s\n", found.size (), reg_names[regno]);
- else
-- log ("modifying %d absolute addresses using %s\n", found.size (), reg_names[regno]);
-+ log ("(b) modifying %d absolute addresses using %s\n", found.size (), reg_names[regno]);
-
- for (auto k = found.begin (); k != found.end (); ++k)
- {
-
-From 7ad7dde941ed115c07b25ab998132282014b7141 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 15 May 2017 15:45:41 +0200
-Subject: [PATCH 119/303] @R undo a stack frame change - no longer needed
-
----
- gcc/config/m68k/m68k.c | 8 +++-----
- 1 file changed, 3 insertions(+), 5 deletions(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 8a40cbc2ab1f..3b51b2541bc9 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -808,11 +808,9 @@ m68k_compute_frame_layout (void)
-
- /* Only compute the frame once per function.
- Don't cache information until reload has been completed. */
-- /* SBF: No. Register renaming may free some variables,
-- * => compute it again and again... */
--// if (current_frame.funcdef_no == current_function_funcdef_no
--// && reload_completed)
--// return;
-+ if (current_frame.funcdef_no == current_function_funcdef_no
-+ && reload_completed)
-+ return;
-
- current_frame.size = (get_frame_size () + 3) & -4;
-
-
-From 06d5805ee8035c3f8e32d7a14fb764bfbd9c2d83 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 15 May 2017 18:06:54 +0200
-Subject: [PATCH 120/303] @B fix #19 - fix stack frame shrinking bugs
-
----
- gcc/bbb-opts.c | 100 ++++++++++++++++++++++++++++++++-------------------------
- 1 file changed, 56 insertions(+), 44 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index ebae14f41832..a997d721d605 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -88,10 +88,10 @@ extern struct lang_hooks lang_hooks;
- /* Lookup of the current function name. */
- extern tree current_function_decl;
- static tree last_function_decl;
-+static char fxname[512];
- static char const *
- get_current_function_name ()
+ if (flag_pic == 1 && TARGET_68020)
+ return "@GOT.w";
+@@ -4671,8 +4836,58 @@ print_operand_address (FILE *file, rtx addr)
{
-- static char fxname[512];
- if (current_function_decl == NULL)
- strcpy (fxname, "<toplevel>");
- else
-@@ -297,6 +297,12 @@ class insn_info
- return src_mem && src_plus;
- }
+ struct m68k_address address;
-+ inline bool
-+ is_dst_mem_plus () const
-+ {
-+ return dst_mem && dst_plus;
-+ }
++#ifdef TARGET_AMIGA
++ /*
++ * SBF: remove the const wrapper.
++ */
++ if (amiga_is_const_pic_ref(addr))
++ {
++ /* handle (plus (unspec ) (const_int) */
++ rtx *x = &addr;
++ while (GET_CODE(*x) != PLUS)
++ x = &XEXP(*x, 0);
+
- inline int
- get_dst_regno () const
- {
-@@ -327,12 +333,24 @@ class insn_info
- return src_mem_reg ? REGNO(src_mem_reg) : -1;
- }
-
-+ inline int
-+ get_dst_mem_regno () const
-+ {
-+ return dst_mem_reg ? REGNO(dst_mem_reg) : -1;
-+ }
++ x = &XEXP(*x, 1); // CONST
++ if (GET_CODE(*x) == CONST)
++ x = &XEXP(*x, 0);
+
- inline int
- get_src_intval () const
- {
- return src_mem_addr;
- }
-
-+ inline int
-+ get_dst_intval () const
-+ {
-+ return dst_mem_addr;
-+ }
++ /* if there is a plus - swap it.
++ * we want n+symbol:W (not symbol:W+n)
++ */
++ if (GET_CODE(*x) == PLUS)
++ {
++ rtx plus = *x;
++ fprintf (file, "%d+", (int) INTVAL (XEXP(plus, 1)));
+
- inline bool
- is_src_const () const
- {
-@@ -2587,6 +2605,12 @@ opt_shrink_stack_frame (void)
- /* check the pushed regs, either a vector or single statements */
- if (GET_CODE(pattern) == PARALLEL)
- {
-+ // do not touch the frame pointer parallel insn.
-+ rtx set = XVECEXP(pattern, 0, 0);
-+ rtx dst = SET_DEST(set);
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-+ continue;
++ *x = XEXP(plus, 0);
++ print_operand_address(file, XEXP(addr, 0));
++ *x = plus;
++ }
++ else
++ print_operand_address(file, XEXP(addr, 0));
+
- std::vector<rtx> regs;
- std::vector<rtx> clobbers;
- for (int j = 0; j < XVECLEN(pattern, 0); ++j)
-@@ -2607,13 +2631,6 @@ opt_shrink_stack_frame (void)
- else
- continue;
++ return;
++ }
++ if (GET_CODE(addr) == PLUS && amiga_is_const_pic_ref(XEXP(addr, 0)))
++ {
++ fprintf (file, "%d+", (int) INTVAL (XEXP(addr, 1)));
++ print_operand_address(file, XEXP(XEXP(addr, 0),0));
++ return;
++ }
++
++
++ if (symbolic_operand(addr, VOIDmode))
++ {
++ memset (&address, 0, sizeof (address));
++ address.offset = addr;
++ }
++ else
++#endif
+ if (!m68k_decompose_address (QImode, addr, true, &address))
+- gcc_unreachable ();
++ {
++ debug_rtx(addr);
++ gcc_unreachable ();
++ }
-- if (REGNO(reg) == FRAME_POINTER_REGNUM)
-- {
-- // mark as "do not touch"
-- clobbers.push_back (reg);
-- break;
-- }
--
- if (i < prologueend)
- paramstart += 4;
- unsigned regbit = 1 << REGNO(reg);
-@@ -2628,19 +2645,16 @@ opt_shrink_stack_frame (void)
- regs.push_back (copy_reg (reg, -1));
+ if (address.code == PRE_DEC)
+ fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
+@@ -4714,6 +4929,14 @@ print_operand_address (FILE *file, rtx addr)
}
-
-- /* don't touch - clobbers! */
-- if (clobbers.size ())
-- continue;
--
-- /* add romm for add.
-+ /* add room for add.
- * push is always using -(a7) addressing.
- * If a5 is used a movem offset(a5) is generated to pop saved registers..
- * Otherwise a7 is used and with (a7)+ addressing.
- */
- int add1 = i < prologueend || !usea5 ? 1 : 0;
-- if ((int) regs.size () + add1 < XVECLEN(pattern, 0) || regs.size () <= 2)
-+ if ((int) regs.size () + add1 + (int) clobbers.size () < XVECLEN(pattern, 0) || regs.size () <= 2)
- {
-- log ("(f) shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1, regs.size ());
-+ log ("(f) shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1 - clobbers.size (),
-+ regs.size ());
- if (regs.size () <= 2)
- {
- changed = 1;
-@@ -2674,17 +2688,19 @@ opt_shrink_stack_frame (void)
- for (unsigned k = 0; k < regs.size (); ++k)
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-
-+ unsigned l = 0;
- /* no add if a5 is used with pop */
- if (!usea5 || i < prologueend)
- {
- plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-- XVECEXP(parallel, 0, 0) = gen_rtx_SET(a7, plus);
-+ XVECEXP(parallel, 0, l) = gen_rtx_SET(a7, plus);
-+ ++l;
- }
-
- if (i >= prologueend)
- x = usea5 ? -x : 0;
-
-- for (unsigned k = 0; k < regs.size (); ++k)
-+ for (unsigned k = 0; k < regs.size (); ++k, ++l)
- {
- if (i < prologueend)
- {
-@@ -2693,7 +2709,7 @@ opt_shrink_stack_frame (void)
- x -= REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
- rtx set = gen_rtx_SET(mem, regs[k]);
-- XVECEXP(parallel, 0, k + 1) = set;
-+ XVECEXP(parallel, 0, l) = set;
- }
- else
- {
-@@ -2704,7 +2720,7 @@ opt_shrink_stack_frame (void)
- plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
- rtx set = gen_rtx_SET(regs[k], mem);
-- XVECEXP(parallel, 0, k) = set;
-+ XVECEXP(parallel, 0, l) = set;
- }
- else
- {
-@@ -2712,10 +2728,16 @@ opt_shrink_stack_frame (void)
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
- rtx set = gen_rtx_SET(regs[k], mem);
-- XVECEXP(parallel, 0, k + 1) = set;
-+ XVECEXP(parallel, 0, l) = set;
- }
- }
- }
+ else
+ output_addr_const (file, addr);
+
-+ for (unsigned k = 0; k < clobbers.size (); ++k)
-+ {
-+ rtx clobber = clobbers[k];
-+ XVECEXP(parallel, 0, l++) = clobber;
-+ }
- emit_insn_after (parallel, insn);
- }
- SET_INSN_DELETED(insn);
-@@ -2761,32 +2783,19 @@ opt_shrink_stack_frame (void)
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-- insn = ii.get_insn ();
-- if (!insn || !INSN_P(insn))
-- continue;
--
-- rtx set = single_set (insn);
-- if (!set)
-- continue;
-+ rtx pattern = PATTERN (ii.get_insn ());
-+ if (ii.is_compare ())
-+ pattern = XEXP(pattern, 1);
-+ if (ii.is_src_mem () && ii.is_src_mem_plus () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM)
++#ifdef TARGET_AMIGA
++ if (SYMBOL_REF_FUNCTION_P(addr))
+ {
-+ rtx plus = XEXP(XEXP(pattern, 1), 0);
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_src_intval () - adjust);
++ if (flag_smallcode)
++ asm_fprintf(file, ":w(pc)");
+ }
-
-- rtx mem = SET_SRC(set);
-- if (MEM_P(mem))
-+ if (ii.is_dst_mem () && ii.is_dst_mem_plus () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM)
- {
-- rtx plus = XEXP(mem, 0);
-- if (GET_CODE(plus) == PLUS)
-- {
-- rtx sp = XEXP(plus, 0);
-- if (REG_P(sp) && REGNO(sp) == STACK_POINTER_REGNUM)
-- {
-- rtx c = XEXP(plus, 1);
-- if (CONST_INT_P(c))
-- {
-- int n = INTVAL(c);
-- if (n >= paramstart)
-- XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, n - adjust);
-- }
-- }
-- }
-+ rtx plus = XEXP(XEXP(pattern, 0), 0);
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_dst_intval () - adjust);
- }
++#endif
}
}
-@@ -3073,6 +3082,9 @@ namespace
- bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
- bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
-
-+ if (be_very_verbose)
-+ log ("ENTER\n");
-+
- for (;;)
- {
- int done = 1;
-
-From 6599877df5f8d490fbbc29a2509dd10137ebb0b4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 15 May 2017 22:20:22 +0200
-Subject: [PATCH 121/303] @B fix #19 - renaming single registers of a register
- pair (long long) is a bad idea...
-
----
- gcc/bbb-opts.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index d0bef1dbc6dc..800f83ea40fe 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -649,6 +649,8 @@ class insn_info
- unsigned
- get_regbit () const
- {
-+ if (GET_MODE_SIZE(mode) > 4)
-+ return 0;
- return def & ~hard & ~use & 0x7fff;
- }
-
-@@ -1539,6 +1541,13 @@ opt_reg_rename (void)
- else if (!(jj.get_use () & rename_regbit))
- break;
-
-+ /* abort if some insn using this reg uses more than 1 reg. */
-+ if ((jj.get_myuse() & rename_regbit) && GET_MODE_SIZE(jj.get_mode()) > 4)
-+ {
-+ mask = 0;
-+ break;
-+ }
-+
- /* update free regs. */
- mask &= ~jj.get_use ();
- mask &= ~jj.get_def ();
-
-From b35c1e12d6be7dfaf301801267ff558f6b149be5 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 16 May 2017 12:47:15 +0200
-Subject: [PATCH 122/303] @B fix recognition of asm function parameters
-
----
- gcc/BASE-VER | 2 +-
- gcc/DATESTAMP | 2 +-
- gcc/config/m68k/amigaos.c | 7 +++++++
- gcc/config/m68k/amigaos.h | 20 --------------------
- gcc/config/m68k/m68kamigaos.h | 18 ++++++++++++++++++
- 5 files changed, 27 insertions(+), 22 deletions(-)
-
-diff --git a/gcc/BASE-VER b/gcc/BASE-VER
-index 76af0075384a..6352d5267189 100644
---- gcc/BASE-VER
-+++ gcc/BASE-VER
-@@ -1 +1 @@
--6.3.1d
-+6.3.1b
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 2f2212531db5..43cf3b2286b6 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170515
-+20170516
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 419d59dc3871..3bd99b5c6389 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -463,6 +463,13 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- DPRINTF(("1amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
- }
-
-+
-+int
-+amigaos_function_arg_reg(unsigned regno)
-+{
-+ return mycum.regs_already_used & (1 << regno) != 0;
-+}
-+
- /* Update the data in CUM to advance over an argument. */
-
- void
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index e2a2b4cc11f6..284328683c37 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -381,31 +381,11 @@ amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
- /* 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 AMIGAOS_MAX_REGPARM
--#define AMIGAOS_MAX_REGPARM 4
--
--/* The default number of data, address and float registers to use when
-- user specified '-mregparm' switch, not '-mregparm=<value>' option. */
--#undef AMIGAOS_DEFAULT_REGPARM
--#define AMIGAOS_DEFAULT_REGPARM 2
--
--
- #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) < AMIGAOS_MAX_REGPARM) \
-- || ((N) >= 8 && (N) < 8 + AMIGAOS_MAX_REGPARM) \
-- || (TARGET_68881 && (N) >= 16 && (N) < 16 + AMIGAOS_MAX_REGPARM))
-
- /*
- On the m68k, this is a structure:
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 3ca2cd666e7c..f636e397cfca 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -670,3 +670,21 @@ extern int amiga_is_const_pic_ref(const_rtx x);
-
- #define EH_TABLES_CAN_BE_READ_ONLY 1
-
-+
-+/* 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 AMIGAOS_MAX_REGPARM
-+#define AMIGAOS_MAX_REGPARM 4
-+
-+/* The default number of data, address and float registers to use when
-+ user specified '-mregparm' switch, not '-mregparm=<value>' option. */
-+#undef AMIGAOS_DEFAULT_REGPARM
-+#define AMIGAOS_DEFAULT_REGPARM 2
-+
-+/* 1 if N is a possible register number for function argument passing. */
-+#undef FUNCTION_ARG_REGNO_P
-+#define FUNCTION_ARG_REGNO_P(N) amigaos_function_arg_reg(N)
-+
-+extern int
-+amigaos_function_arg_reg(unsigned regno);
-
-From 42f9687b3643a14d216c68b685a8b79f0e860c0e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 16 May 2017 12:50:48 +0200
-Subject: [PATCH 123/303] @B fix recognition of asm function parameters
-
----
- gcc/config/m68k/amigaos.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 3bd99b5c6389..9166b91a69eb 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -467,7 +467,7 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- int
- amigaos_function_arg_reg(unsigned regno)
- {
-- return mycum.regs_already_used & (1 << regno) != 0;
-+ return (mycum.regs_already_used & (1 << regno)) != 0;
- }
-
- /* Update the data in CUM to advance over an argument. */
-
-From 97158247a4a2e85140f33ab30a1a8a8802744e64 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 17 May 2017 09:34:58 +0200
-Subject: [PATCH 124/303] @B analyse jump_tables for correct flow and register
- usage analysis
-
----
- gcc/bbb-opts.c | 121 ++++++++++++++++++++++++++++++++++++++++++---------------
- 1 file changed, 90 insertions(+), 31 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 800f83ea40fe..e49148416a43 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -943,10 +943,12 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- * Collect some data.
- */
- static std::vector<insn_info> infos;
--static std::vector<rtx_insn *> jumps;
--static std::map<rtx_insn *, insn_info *> insn2index;
- typedef std::vector<insn_info>::iterator insn_info_iterator;
--typedef std::vector<rtx_insn *>::iterator rtx_insn_iterator;
-+
-+static std::multimap<int, rtx_insn *> label2jump;
-+typedef std::multimap<int, rtx_insn *>::iterator l2j_iterator;
-+
-+static std::map<rtx_insn *, insn_info *> insn2index;
- typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
-
- static insn_info * info0;
-@@ -1122,7 +1124,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- static void
- clear (void)
- {
-- jumps.clear ();
-+ label2jump.clear ();
- insn2index.clear ();
- infos.clear ();
- }
-@@ -1154,7 +1156,7 @@ void
- append_reg_usage (FILE * f, rtx_insn * insn)
- {
+ else
+@@ -5155,7 +5378,9 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
-- i2i_iterator i = insn2index.find (insn);
-+ i2i_iterator i = insn2index.find (insn);
- if (i == insn2index.end ())
- return;
+ /* Value is true if hard register REGNO can hold a value of machine-mode
+ MODE. On the 68000, we let the cpu registers can hold any mode, but
+- restrict the 68881 registers to floating-point modes. */
++ restrict the 68881 registers to floating-point modes.
++ SBF: Disallow the frame pointer register, if the frame pointer is used.
++ */
-@@ -1262,14 +1264,12 @@ update_insn_infos (void)
- if (LABEL_P(insn))
- {
- /* work on all jumps referring to that label. */
-- for (rtx_insn_iterator i = jumps.begin (); i != jumps.end (); ++i)
-+ for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
-+ i != label2jump.end () && i->first == k->first; ++i)
- {
-- if (JUMP_LABEL(*i) == insn)
-- {
-- i2i_iterator j = insn2index.find (*i);
-- if (j != insn2index.end ())
-- todo.push_back (std::make_pair (j->second->get_index (), ii));
-- }
-+ i2i_iterator j = insn2index.find (i->second);
-+ if (j != insn2index.end ())
-+ todo.push_back (std::make_pair (j->second->get_index (), ii));
- }
- continue;
- }
-@@ -1299,7 +1299,7 @@ update_insn_infos (void)
- if (!use.is_def (FIRST_PSEUDO_REGISTER))
- {
- CC_STATUS_INIT;
-- NOTICE_UPDATE_CC (PATTERN (insn), insn);
-+ NOTICE_UPDATE_CC(PATTERN (insn), insn);
- if (cc_status.value1 || cc_status.value2)
- use.mark_def (FIRST_PSEUDO_REGISTER);
- }
-@@ -1340,10 +1340,13 @@ update_insn_infos (void)
- /*
- * Create a filtered view of insns - keep only those to work with.
- */
--static void
-+static int
- update_insns ()
+ bool
+ m68k_regno_mode_ok (int regno, machine_mode mode)
+@@ -5169,7 +5394,7 @@ m68k_regno_mode_ok (int regno, machine_mode mode)
+ else if (ADDRESS_REGNO_P (regno))
+ {
+ if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
+- return true;
++ return !frame_pointer_needed || regno != FRAME_POINTER_REGNUM;
+ }
+ else if (FP_REGNO_P (regno))
+ {
+@@ -5190,6 +5415,13 @@ m68k_secondary_reload_class (enum reg_class rclass,
+ machine_mode mode, rtx x)
{
- rtx_insn *insn, *next;
-+
-+ rtx jump_table = 0;
-+
- clear ();
-
- char inproepilogue = 1;
-@@ -1360,10 +1363,50 @@ update_insns ()
+ int regno;
++#ifdef TARGET_AMIGA
++ /* SBF: check for baserel's const pic_ref
++ * and return ADDR_REGS or NO_REGS
++ */
++ if (!MEM_P(x) && amiga_is_const_pic_ref(x))
++ return rclass == ADDR_REGS ? NO_REGS : ADDR_REGS;
++#endif
- if (JUMP_P(insn))
- {
-- jumps.push_back (insn);
- inproepilogue = 0;
+ regno = true_regnum (x);
- ii.mark_jump ();
-+
-+ rtx pattern = PATTERN (insn);
-+ if (GET_CODE(pattern) == PARALLEL)
-+ {
-+ /*
-+ * Use the jump_table_data and add all to the lookup
-+ */
-+ if (jump_table == 0)
-+ {
-+ // still allow complex if_then_else which are also in parallel
-+ rtx ite = XVECEXP(insn, 0, 0);
-+ if (XEXP(ite, 0) != pc_rtx || GET_CODE(XEXP(ite, 1)) != IF_THEN_ELSE)
-+ {
-+ debug_rtx(insn);
-+ return 1; // do not optimize.
-+ }
-+ }
-+ else
-+ if (XEXP(jump_table, 0) != insn)
-+ {
-+ debug_rtx(insn);
-+ return 2;
-+ }
-+
-+ // -> jump_table_data
-+ rtx table = PATTERN (XEXP(jump_table, 1));
-+ for (int j = 0; j < XVECLEN(table, 1); ++j)
-+ {
-+ rtx ref = XVECEXP(table, 1, j);
-+ rtx label = XEXP(ref, 0);
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ }
-+
-+ jump_table = 0;
-+ }
-+ else
-+ {
-+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ }
-+
- }
- else if (LABEL_P(insn))
- {
-@@ -1378,6 +1421,16 @@ update_insns ()
- rtx set = single_set (insn);
- if (set)
- ii.fledder (set);
-+
-+ for (rtx next, note = REG_NOTES(insn); note; note = next)
-+ {
-+ next = XEXP(note, 1);
-+ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND)
-+ {
-+ jump_table = XEXP(note, 0);
-+ }
-+ }
-+
- }
- }
+diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
+index 2aa858fa23b5..442a84e6a883 100644
+--- gcc/config/m68k/m68k.h
++++ gcc/config/m68k/m68k.h
+@@ -204,7 +204,11 @@ along with GCC; see the file COPYING3. If not see
+ #define INT_OP_DC 3 /* dc.b, dc.w, dc.l */
-@@ -1392,6 +1445,8 @@ update_insns ()
+ /* Set the default. */
++#ifndef TARGET_AMIGAOS_VASM
+ #define INT_OP_GROUP INT_OP_DOT_WORD
++#else
++#define INT_OP_GROUP INT_OP_DC
++#endif
- update_insn2index ();
- update_insn_infos ();
-+
-+ return 0;
+ /* Bit values used by m68k-devices.def to identify processor capabilities. */
+ #define FL_BITFIELD (1 << 0) /* Support bitfield instructions. */
+@@ -378,14 +382,13 @@ along with GCC; see the file COPYING3. If not see
+ { /* d0/d1/a0/a1 */ \
+ 0, 1, 8, 9, \
+ /* d2-d7 */ \
+- 2, 3, 4, 5, 6, 7, \
++ 2, 10, 3, 11, 4, 5, 6, 7, \
+ /* a2-a7/arg */ \
+- 10, 11, 12, 13, 14, 15, 24, \
++ 12, 13, 14, 15, 24, \
+ /* fp0-fp7 */ \
+ 16, 17, 18, 19, 20, 21, 22, 23\
}
- /* convert the lowest set bit into a register number. */
-@@ -1505,21 +1560,19 @@ opt_reg_rename (void)
- * check if the reg was used at that jump.
- * if used, find def
- */
-- for (rtx_insn_iterator i = jumps.begin (); i != jumps.end (); ++i)
-+ for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
-+ i != label2jump.end () && i->first == k->first; ++i)
- {
-- if (JUMP_LABEL(*i) == insn)
-- {
-- i2i_iterator j = insn2index.find (*i);
-- if (j == insn2index.end ())
-- continue;
-+ i2i_iterator j = insn2index.find (i->second);
-+ if (j == insn2index.end ())
-+ continue;
-
-- unsigned start = j->second->get_index ();
-- if (!infos[start].is_use (rename_regno))
-- continue;
-+ unsigned start = j->second->get_index ();
-+ if (!infos[start].is_use (rename_regno))
-+ continue;
-
-- start = find_start (found, start, rename_regno);
-- todo.push_back (start);
-- }
-+ start = find_start (found, start, rename_regno);
-+ todo.push_back (start);
- }
- continue;
- }
-@@ -1542,7 +1595,7 @@ opt_reg_rename (void)
- break;
-
- /* abort if some insn using this reg uses more than 1 reg. */
-- if ((jj.get_myuse() & rename_regbit) && GET_MODE_SIZE(jj.get_mode()) > 4)
-+ if ((jj.get_myuse () & rename_regbit) && GET_MODE_SIZE(jj.get_mode()) > 4)
- {
- mask = 0;
- break;
-@@ -1987,7 +2040,7 @@ opt_strcpy ()
- if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 && is_reg_dead (REGNO(dst), index))
- {
- /* now check via NOTICE_UPDATE_CC*/
-- NOTICE_UPDATE_CC (PATTERN (reg2x), reg2x);
-+ NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
- if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2))
- {
- int num_clobbers_to_add = 0;
-@@ -2375,7 +2428,7 @@ opt_merge_add (void)
- rtx_insn * insn1 = ii1.get_insn ();
-
- CC_STATUS_INIT;
-- NOTICE_UPDATE_CC (PATTERN (insn1), insn1);
-+ NOTICE_UPDATE_CC(PATTERN (insn1), insn1);
- if (cc_status.value1 || cc_status.value2)
- continue;
-
-@@ -3091,7 +3144,13 @@ namespace
- for (;;)
- {
- int done = 1;
-- update_insns ();
-+ int r = update_insns ();
-+ if (r)
-+ {
-+ if (be_verbose)
-+ log("no bbb optimization code %d\n", r);
-+ return 0;
-+ }
- if (do_opt_strcpy && opt_strcpy ())
- done = 0, update_insns ();
-
-
-From d49f98c1822e1a810d81048c0082ebec69a5d66f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 17 May 2017 11:12:25 +0200
-Subject: [PATCH 125/303] @B support if_then_else inside of parallel insns
-
----
- gcc/DATESTAMP | 2 +-
- gcc/bbb-opts.c | 37 ++++++++++++++++++-------------------
- 2 files changed, 19 insertions(+), 20 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 43cf3b2286b6..f9bb1bba46d4 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170516
-+20170517
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index e49148416a43..7fa077167ef2 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1375,30 +1375,32 @@ update_insns ()
- */
- if (jump_table == 0)
- {
-- // still allow complex if_then_else which are also in parallel
-- rtx ite = XVECEXP(insn, 0, 0);
-+ // still allow if_then_else inside a parallel insn
-+ rtx ite = XVECEXP(pattern, 0, 0);
- if (XEXP(ite, 0) != pc_rtx || GET_CODE(XEXP(ite, 1)) != IF_THEN_ELSE)
- {
-- debug_rtx(insn);
-+ debug_rtx (insn);
- return 1; // do not optimize.
- }
-+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
- }
-- else
-- if (XEXP(jump_table, 0) != insn)
-+ else if (XEXP(jump_table, 0) != insn)
- {
-- debug_rtx(insn);
-+ debug_rtx (insn);
- return 2;
- }
--
-- // -> jump_table_data
-- rtx table = PATTERN (XEXP(jump_table, 1));
-- for (int j = 0; j < XVECLEN(table, 1); ++j)
-+ else
- {
-- rtx ref = XVECEXP(table, 1, j);
-- rtx label = XEXP(ref, 0);
-- label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ // -> jump_table_data
-+ rtx table = PATTERN (XEXP(jump_table, 1));
-+ for (int j = 0; j < XVECLEN(table, 1); ++j)
-+ {
-+ rtx ref = XVECEXP(table, 1, j);
-+ rtx label = XEXP(ref, 0);
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ }
- }
--
- jump_table = 0;
- }
- else
-@@ -1433,8 +1435,7 @@ update_insns ()
-
- }
- }
--
-- if (NOTE_P(insn))
-+ else if (NOTE_P(insn))
- {
- if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
- inproepilogue = 0;
-@@ -2051,8 +2052,6 @@ opt_strcpy ()
- insn_code_number = recog (PATTERN (newinsn), newinsn, &num_clobbers_to_add);
- if (insn_code_number >= 0 && check_asm_operands (PATTERN (newinsn)))
- {
-- rtx link;
-
- log ("(s) opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
- reg_names[REGNO(dst)]);
-
-@@ -3148,7 +3147,7 @@ namespace
- if (r)
- {
- if (be_verbose)
-- log("no bbb optimization code %d\n", r);
-+ log ("no bbb optimization code %d\n", r);
- return 0;
- }
- if (do_opt_strcpy && opt_strcpy ())
-
-From 7c4335944b40ed8cac718f17a3492b543589c1e9 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 17 May 2017 13:44:06 +0200
-Subject: [PATCH 126/303] @B fix absolute optimization
-
----
- gcc/bbb-opts.c | 10 ++--------
- 1 file changed, 2 insertions(+), 8 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 7fa077167ef2..adc21bf4e39e 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1081,7 +1081,8 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- else
- dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
+ /* On the m68k, ordinary registers hold 32 bits worth;
+ for the 68881 registers, a single register is always enough for
+ anything that can be stored in them at all. */
+@@ -440,8 +443,8 @@ along with GCC; see the file COPYING3. If not see
+ /* The m68k has three kinds of registers, so eight classes would be
+ a complete set. One of them is not needed. */
+ enum reg_class {
+- NO_REGS, DATA_REGS,
+- ADDR_REGS, FP_REGS,
++ NO_REGS, DATA_REGS, D0_REGS,
++ ADDR_REGS, A0_REGS, FP_REGS,
+ GENERAL_REGS, DATA_OR_FP_REGS,
+ ADDR_OR_FP_REGS, ALL_REGS,
+ LIM_REG_CLASSES };
+@@ -449,8 +452,8 @@ enum reg_class {
+ #define N_REG_CLASSES (int) LIM_REG_CLASSES
-- if (src_plus && rtx_equal_p (olddst, XEXP(src, 0)))
-+ /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */
-+ if (src_op && rtx_equal_p (olddst, XEXP(src, 0)))
- XEXP(src, 0) = dst;
+ #define REG_CLASS_NAMES \
+- { "NO_REGS", "DATA_REGS", \
+- "ADDR_REGS", "FP_REGS", \
++ { "NO_REGS", "DATA_REGS", "D0_REGS" \
++ "ADDR_REGS", "A0_REGS", "FP_REGS", \
+ "GENERAL_REGS", "DATA_OR_FP_REGS", \
+ "ADDR_OR_FP_REGS", "ALL_REGS" }
- dst_mem_reg = reg;
-@@ -2950,13 +2951,6 @@ opt_absolute (void)
- && jj.get_src_symbol () == with_symbol;
+@@ -458,7 +461,9 @@ enum reg_class {
+ { \
+ {0x00000000}, /* NO_REGS */ \
+ {0x000000ff}, /* DATA_REGS */ \
++ {0x00000001}, /* D0_REGS */ \
+ {0x0100ff00}, /* ADDR_REGS */ \
++ {0x00000100}, /* A0_REGS */ \
+ {0x00ff0000}, /* FP_REGS */ \
+ {0x0100ffff}, /* GENERAL_REGS */ \
+ {0x00ff00ff}, /* DATA_OR_FP_REGS */ \
+@@ -614,11 +619,11 @@ __transfer_from_trampoline () \
- /* exclude operations on that symbol. */
-- pattern = PATTERN (jj.get_insn ());
-- if (j_dst && !jj.get_src_reg () && !jj.is_src_const ())
-- if (MEM_P(XEXP(XEXP(pattern, 1), 0)))
-- continue;
-- if (j_src && !jj.get_dst_reg ())
-- if (MEM_P(XEXP(XEXP(pattern, 0), 0)))
-- continue;
+ #define REGNO_OK_FOR_INDEX_P(REGNO) \
+ (INT_REGNO_P (REGNO) \
+- || INT_REGNO_P (reg_renumber[REGNO]))
++ || (reg_renumber && INT_REGNO_P (reg_renumber[REGNO])))
- if (j_dst)
- {
-
-From f89679a40f70cf28bfe2e5b9cec347b292df4d1c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 17 May 2017 20:55:45 +0200
-Subject: [PATCH 127/303] @B fix reading insn like lea 1(a0),a1 - to extract
- the correct source register
-
----
- gcc/bbb-opts.c | 49 +++++++++++++++++++++++++------------------------
- 1 file changed, 25 insertions(+), 24 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index adc21bf4e39e..37fc9dbd01fc 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -815,6 +815,25 @@ insn_info::fledder (rtx set)
- }
- }
+ #define REGNO_OK_FOR_BASE_P(REGNO) \
+ (ADDRESS_REGNO_P (REGNO) \
+- || ADDRESS_REGNO_P (reg_renumber[REGNO]))
++ || (reg_renumber && ADDRESS_REGNO_P (reg_renumber[REGNO])))
-+ /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */
-+ rtx alt_src_reg = 0;
-+ int code = GET_CODE(src);
-+ if (!REG_P(src) && !MEM_P(src) && code != CONST_INT && code != CONST && code != CONST_WIDE_INT && code != CONST_DOUBLE
-+ && code != CONST_FIXED && code != CONST_STRING)
-+ {
-+ src_op = GET_CODE(src);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ if (fmt[0] == 'e' && fmt[1] == 'e')
-+ {
-+ rtx operand = XEXP(src, 1);
-+ if (GET_CODE(operand) == CONST_INT)
-+ src_const = true, src_mem_addr = INTVAL(operand);
-+ else if (REG_P(operand))
-+ alt_src_reg = operand;
-+ }
-+ src = XEXP(src, 0);
-+ }
+ #define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
+ (INT_REGNO_P (REGNO) \
+@@ -727,9 +732,49 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
+ if (cc_prev_status.flags & CC_NO_OVERFLOW) \
+ return NO_OV; \
+ return NORMAL; } while (0)
+
- if (REG_P(src))
- {
- src_reg = src;
-@@ -861,29 +880,8 @@ insn_info::fledder (rtx set)
- src_const = true;
- src_mem_addr = INTVAL(src);
- }
-- /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */
-- if (*GET_RTX_FORMAT(GET_CODE(src)) == 'e')
-- {
-- src_op = GET_CODE(src);
-- rtx reg = XEXP(src, 0);
-- if (REG_P(reg) && GET_RTX_LENGTH(GET_CODE(src)) >= 2)
-- {
-- rtx konst = XEXP(src, 1);
-- src_reg = reg;
-- if (konst)
-- {
-- if (GET_CODE(konst) == CONST_INT)
-- {
-- src_const = true;
-- src_mem_addr = INTVAL(konst);
-- }
-- else if (REG_P(konst))
-- {
-- src_reg = konst; /* dst_reg = dst_reg OP src_reg: store src_reg not dst_reg */
-- }
-- }
-- }
-- }
-+ if (alt_src_reg)
-+ src_reg = alt_src_reg;
- }
-
- /* create a copy for a reg. Optional specify a new register number. */
-@@ -2844,7 +2842,10 @@ opt_shrink_stack_frame (void)
- pattern = XEXP(pattern, 1);
- if (ii.is_src_mem () && ii.is_src_mem_plus () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM)
- {
-- rtx plus = XEXP(XEXP(pattern, 1), 0);
-+ rtx src = XEXP(pattern, 1);
-+ rtx plus = XEXP(src, 0);
-+ if (ii.get_src_op ())
-+ plus = XEXP(plus, 0);
- XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_src_intval () - adjust);
- }
-
-
-From aa46f14ae49b802ed71bc0fa238045089ede31da Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 17 May 2017 23:29:00 +0200
-Subject: [PATCH 128/303] @B fix operations on symbol/absolute are now
- correctly converted int operations on address reg
-
----
- gcc/bbb-opts.c | 68 ++++++++++++++++++++++++++++++++++------------------------
- 1 file changed, 40 insertions(+), 28 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 37fc9dbd01fc..5cce787b0d27 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -139,7 +139,8 @@ class insn_info
- bool src_mem;
- bool dst_plus;
- bool src_plus;
-- int src_op;
-+ rtx_code src_op;
-+ bool src_ee;
- bool src_const;
-
- machine_mode mode;
-@@ -151,15 +152,15 @@ class insn_info
- rtx src_mem_reg;
- rtx src_symbol;
- unsigned dst_mem_addr;
--
-+ int src_intval;
- unsigned src_mem_addr;
-
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
-- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (0), src_const (
-- false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (
-- 0), dst_mem_addr (0), src_mem_addr (0)
-+ false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
-+ (rtx_code) 0), src_ee (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (
-+ 0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (0)
- {
- }
-
-@@ -265,7 +266,7 @@ class insn_info
- }
-
- inline unsigned
-- get_src_addr () const
-+ get_src_mem_addr () const
- {
- return src_mem_addr;
- }
-@@ -282,6 +283,12 @@ class insn_info
- return src_op;
- }
-
-+ inline bool
-+ is_src_ee () const
-+ {
-+ return src_ee;
-+ }
++#ifdef TARGET_AMIGAOS_VASM
++#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
++ do { \
++ FILE *_hide_asm_out_file = (MYFILE); \
++ const unsigned char *_hide_p = (const unsigned char *) (MYSTRING); \
++ int _hide_thissize = (MYLENGTH); \
++ { \
++ FILE *asm_out_file = _hide_asm_out_file; \
++ const unsigned char *p = _hide_p; \
++ int thissize = _hide_thissize; \
++ int i; \
++ fprintf (asm_out_file, "\tdc.b \""); \
++ \
++ for (i = 0; i < thissize; i++) \
++ { \
++ int c = p[i]; \
++ if (c == '\"' || c == '\\') \
++ putc ('\\', asm_out_file); \
++ if (ISPRINT (c)) \
++ putc (c, asm_out_file); \
++ else \
++ { \
++ fprintf (asm_out_file, "\\%o", c); \
++ /* After an octal-escape, if a digit follows, \
++ terminate one string constant and start another. \
++ The VAX assembler fails to stop reading the escape \
++ after three digits, so this is the only way we \
++ can get it to parse the data properly. */ \
++ if (i < thissize - 1 && ISDIGIT (p[i + 1])) \
++ fprintf (asm_out_file, "\"\n\tdc.b \""); \
++ } \
++ } \
++ fprintf (asm_out_file, "\"\n"); \
++ } \
++ } \
++ while (0)
++#endif
+
+
- inline bool
- is_src_mem_plus () const
- {
-@@ -333,7 +340,7 @@ class insn_info
- inline int
- get_src_intval () const
- {
-- return src_mem_addr;
-+ return src_intval;
- }
-
- inline int
-@@ -417,7 +424,8 @@ class insn_info
- src_mem = false;
- dst_plus = false;
- src_plus = false;
-- src_op = 0;
-+ src_op = (rtx_code)0;
-+ src_ee = false;
- src_const = false;
-
- mode = VOIDmode;
-@@ -430,6 +438,7 @@ class insn_info
- src_symbol = 0;
- dst_mem_addr = 0;
+ /* Control the assembler format that we output. */
-+ src_intval = 0;
- src_mem_addr = 0;
- }
++#ifndef TARGET_AMIGAOS_VASM
+ #define ASM_APP_ON "#APP\n"
+ #define ASM_APP_OFF "#NO_APP\n"
+ #define TEXT_SECTION_ASM_OP "\t.text"
+@@ -739,6 +784,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
+ #define LOCAL_LABEL_PREFIX ""
+ #define USER_LABEL_PREFIX "_"
+ #define IMMEDIATE_PREFIX "#"
++#else
++#define ASM_APP_ON ""
++#define ASM_APP_OFF ""
++#define TEXT_SECTION_ASM_OP "\tsection .text"
++#define DATA_SECTION_ASM_OP "\tsection .data"
++#define GLOBAL_ASM_OP "\txdef\t"
++#define REGISTER_PREFIX ""
++#define LOCAL_LABEL_PREFIX "_."
++#define USER_LABEL_PREFIX "_"
++#define IMMEDIATE_PREFIX "#"
++#endif
-@@ -818,16 +827,17 @@ insn_info::fledder (rtx set)
- /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */
- rtx alt_src_reg = 0;
- int code = GET_CODE(src);
-- if (!REG_P(src) && !MEM_P(src) && code != CONST_INT && code != CONST && code != CONST_WIDE_INT && code != CONST_DOUBLE
-+ if (!REG_P(src) && !MEM_P(src) && code != CONST_INT && code != CONST && code != CONST_WIDE_INT && code != CONST_DOUBLE
- && code != CONST_FIXED && code != CONST_STRING)
- {
- src_op = GET_CODE(src);
- const char *fmt = GET_RTX_FORMAT(code);
- if (fmt[0] == 'e' && fmt[1] == 'e')
- {
-+ src_ee = true;
- rtx operand = XEXP(src, 1);
-- if (GET_CODE(operand) == CONST_INT)
-- src_const = true, src_mem_addr = INTVAL(operand);
-+ if (GET_CODE(operand) == CONST_INT || GET_CODE(operand) == CONST_WIDE_INT)
-+ src_const = true, src_intval = INTVAL(operand);
- else if (REG_P(operand))
- alt_src_reg = operand;
- }
-@@ -992,7 +1002,7 @@ void
- insn_info::plus_to_move (rtx_insn * newinsn)
- {
- insn = newinsn;
-- src_op = 0;
-+ src_op = (rtx_code)0;
- src_reg = XEXP(PATTERN (newinsn), 1);
- insn2index.insert (std::make_pair (insn, this));
- // usage flags did not change
-@@ -1079,10 +1089,6 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- else
- dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
+ #define REGISTER_NAMES \
+ {REGISTER_PREFIX"d0", REGISTER_PREFIX"d1", REGISTER_PREFIX"d2", \
+@@ -858,11 +914,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-- /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */
-- if (src_op && rtx_equal_p (olddst, XEXP(src, 0)))
-- XEXP(src, 0) = dst;
+ /* The m68k does not use absolute case-vectors, but we must define this macro
+ anyway. */
+-#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
++#ifndef TARGET_AMIGAOS_VASM
++#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ asm_fprintf (FILE, "\t.long %LL%d\n", VALUE)
-
- dst_mem_reg = reg;
- dst_mem = true;
- dst_mem_addr = offset;
-@@ -1092,7 +1098,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
-
- if (is_src_mem () && (has_src_addr () || get_src_symbol ()) && !has_src_memreg () && get_src_symbol () == with_symbol)
- {
-- unsigned addr = get_src_addr ();
-+ unsigned addr = get_src_mem_addr ();
- unsigned offset = addr - base;
- if (offset <= 0x7ffe)
- {
-@@ -1101,6 +1107,15 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- else
- src = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-
-+ /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */
-+ if (src_op)
-+ {
-+ if (src_ee)
-+ src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
-+ else
-+ src = gen_rtx_fmt_e(src_op, mode, src);
-+ }
-+
- src_mem_reg = reg;
- src_mem = true;
- src_mem_addr = offset;
-@@ -2846,7 +2861,7 @@ opt_shrink_stack_frame (void)
- rtx plus = XEXP(src, 0);
- if (ii.get_src_op ())
- plus = XEXP(plus, 0);
-- XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_src_intval () - adjust);
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_src_mem_addr () - adjust);
- }
-
- if (ii.is_dst_mem () && ii.is_dst_mem_plus () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM)
-@@ -2904,6 +2919,9 @@ opt_absolute (void)
- if (ii.is_compare ())
- continue;
+-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
++#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
+ asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL)
++#else
++#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
++ asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
++#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
++ asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
++#endif
-+ if (ii.get_src_op () && ii.is_src_ee () && !ii.get_src_intval ())
-+ continue;
-+
- bool is_dst = ii.is_dst_mem () && (ii.has_dst_addr () || ii.get_dst_symbol ()) && !ii.has_dst_memreg ();
- bool is_src = ii.is_src_mem () && (ii.has_src_addr () || ii.get_src_symbol ()) && !ii.has_src_memreg ();
+ /* We don't have a way to align to more than a two-byte boundary, so do the
+ best we can and don't complain. */
+@@ -872,13 +934,24 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-@@ -2917,15 +2935,6 @@ opt_absolute (void)
- if (!freemask)
- continue;
+ #ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
+ /* Use "move.l %a4,%a4" to advance within code. */
++#ifndef TARGET_AMIGAOS_VASM
+ #define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
+ if ((LOG) > 0) \
+ fprintf ((FILE), "\t.balignw %u,0x284c\n", 1 << (LOG));
+ #endif
++#else
++#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
++ if ((LOG) > 0) \
++ fprintf ((FILE), "\tcnop 0,%u\n", 1 << (LOG));
++#endif
-- /* exclude operations on that symbol. */
-- rtx pattern = PATTERN (ii.get_insn ());
-- if (is_dst && !ii.get_src_reg () && !ii.is_src_const ())
-- if (MEM_P(XEXP(XEXP(pattern, 1), 0)))
-- continue;
-- if (is_src && !ii.get_dst_reg ())
-- if (MEM_P(XEXP(XEXP(pattern, 0), 0)))
-- continue;
--
- rtx with_symbol = is_dst ? ii.get_dst_symbol () : ii.get_src_symbol ();
++#ifndef TARGET_AMIGAOS_VASM
+ #define ASM_OUTPUT_SKIP(FILE,SIZE) \
+ fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
++#else
++#define ASM_OUTPUT_SKIP(FILE,SIZE) \
++ fprintf (FILE, "\tds.b %u\n", (int)(SIZE))
++#endif
- std::vector<unsigned> found;
-@@ -2946,6 +2955,9 @@ opt_absolute (void)
- if (jj.get_mode () == VOIDmode || jj.is_compare ())
- continue;
+ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
+ ( fputs (".comm ", (FILE)), \
+@@ -971,3 +1044,8 @@ extern int m68k_sched_address_bypass_p (rtx_insn *, rtx_insn *);
+ extern int m68k_sched_indexed_address_bypass_p (rtx_insn *, rtx_insn *);
-+ if (jj.get_src_op () && jj.is_src_ee () && !jj.get_src_intval ())
-+ continue;
+ #define CPU_UNITS_QUERY 1
+
- bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ()) && !jj.has_dst_memreg ()
- && jj.get_dst_symbol () == with_symbol;
- bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ()) && !jj.has_src_memreg ()
-@@ -2975,7 +2987,7 @@ opt_absolute (void)
- }
- if (j_src)
- {
-- unsigned addr = jj.get_src_addr ();
-+ unsigned addr = jj.get_src_mem_addr ();
- if (addr < base)
- {
- if (max - addr <= 0x7ffe)
-
-From edca4acf887636033d51096888e751820ef9718d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 18 May 2017 00:00:26 +0200
-Subject: [PATCH 129/303] @B fix opt_absolute for SIGN_EXTEND (ext.*)
-
----
- gcc/bbb-opts.c | 20 ++++++++++++++++----
- 1 file changed, 16 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 5cce787b0d27..dd2923873c1d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1113,7 +1113,14 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- if (src_ee)
- src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
- else
-- src = gen_rtx_fmt_e(src_op, mode, src);
-+ {
-+ if (src_op == SIGN_EXTEND)
-+ {
-+ PUT_MODE_RAW(src, mode == SImode ? HImode : mode == HImode ? QImode : SImode);
-+ src->call = 1;
-+ }
-+ src = gen_rtx_fmt_e(src_op, mode, src);
-+ }
- }
-
- src_mem_reg = reg;
-@@ -2945,12 +2952,17 @@ opt_absolute (void)
- for (; j < infos.size (); ++j)
- {
- insn_info & jj = infos[j];
-- if (jj.is_label () || jj.is_jump () || jj.is_call ())
-+ /* TODO: continue also at jump target */
-+ if (jj.is_jump())
-+ continue;
-+ /* TODO: check if label is visited only from jump targets from herein. then the label is ok. */
-+ if (jj.is_label ())
- break;
-
-- freemask &= ~(jj.get_use () | jj.get_def ());
-- if (!freemask)
-+ unsigned tempmask = freemask & ~(jj.get_use () | jj.get_def ());
-+ if (!tempmask)
- break;
-+ freemask = tempmask;
++#if 1
++extern void default_stabs_asm_out_constructor (rtx, int);
++extern void default_stabs_asm_out_destructor (rtx, int);
++#endif
+diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
+index ec37bd76f55f..05ef02027f01 100644
+--- gcc/config/m68k/m68k.md
++++ gcc/config/m68k/m68k.md
+@@ -128,13 +128,11 @@
+ (UNSPECV_TAS_2 4)
+ ])
- if (jj.get_mode () == VOIDmode || jj.is_compare ())
- continue;
-
-From 90e72be90df0d966c935ae3c91476af65f18cb81 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 20 May 2017 17:02:09 +0200
-Subject: [PATCH 130/303] @B do not optimize with indirect jumps and unknown
- labels. @R doo not indicate regs for static_chain/struct_value if not used
-
----
- gcc/DATESTAMP | 2 +-
- gcc/bbb-opts.c | 151 ++++++++++++++++++++++++++--------------------
- gcc/config/m68k/amigaos.c | 68 ++++++++++++---------
- gcc/config/m68k/amigaos.h | 11 ++++
- 4 files changed, 138 insertions(+), 94 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index f9bb1bba46d4..3f03e820cb0b 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170517
-+20170520
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index dd2923873c1d..848c18e3be52 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -424,7 +424,7 @@ class insn_info
- src_mem = false;
- dst_plus = false;
- src_plus = false;
-- src_op = (rtx_code)0;
-+ src_op = (rtx_code) 0;
- src_ee = false;
- src_const = false;
+-;; Registers by name.
++;; Registers by name. SBF: Do not define PIC_REG / A6_REG here!
+ (define_constants
+ [(D0_REG 0)
+ (A0_REG 8)
+ (A1_REG 9)
+- (PIC_REG 13)
+- (A6_REG 14)
+ (SP_REG 15)
+ (FP0_REG 16)
+ ])
+@@ -1566,7 +1564,7 @@
+ ;; so we will prefer it to them.
-@@ -888,7 +888,7 @@ insn_info::fledder (rtx set)
- else if (GET_CODE(src) == CONST_INT)
- {
- src_const = true;
-- src_mem_addr = INTVAL(src);
-+ src_intval = INTVAL(src);
- }
- if (alt_src_reg)
- src_reg = alt_src_reg;
-@@ -1002,7 +1002,7 @@ void
- insn_info::plus_to_move (rtx_insn * newinsn)
- {
- insn = newinsn;
-- src_op = (rtx_code)0;
-+ src_op = (rtx_code) 0;
- src_reg = XEXP(PATTERN (newinsn), 1);
- insn2index.insert (std::make_pair (insn, this));
- // usage flags did not change
-@@ -1358,14 +1358,19 @@ update_insn_infos (void)
- usable_regs &= ~(1 << STACK_POINTER_REGNUM);
- }
+ (define_insn "pushasi"
+- [(set (match_operand:SI 0 "push_operand" "=m")
++ [(set (match_operand:SI 0 "push_operand" "=<")
+ (match_operand:SI 1 "address_operand" "p"))]
+ ""
+ "pea %a1"
+@@ -7204,6 +7202,7 @@
+ "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
-+enum AbortCodes
-+{
-+ E_OK, E_NO_JUMP_LABEL, E_JUMP_TABLE_MISMATCH, E_JUMP_GOTO_LABEL
-+};
-+
- /*
- * Create a filtered view of insns - keep only those to work with.
- */
--static int
-+static unsigned
- update_insns ()
+ ;; Changing pea X.w into a move.l is no real win here.
++;; SBF: also disable converting pea for baserel insns!
+ (define_peephole2
+ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
+ (match_operand:SI 0 "const_int_operand" "")))
+@@ -7213,7 +7212,8 @@
+ && !reg_mentioned_p (stack_pointer_rtx, operands[2])
+ && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
+ && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
+- && !valid_mov3q_const (INTVAL (operands[2])))"
++ && !valid_mov3q_const (INTVAL (operands[2])))
++ && !amiga_is_const_pic_ref(operands[2])"
+ [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
+ (set (match_dup 1) (match_dup 2))]
{
- rtx_insn *insn, *next;
--
-+ unsigned result = 0;
- rtx jump_table = 0;
-
- clear ();
-@@ -1386,54 +1391,69 @@ update_insns ()
- {
- inproepilogue = 0;
-
-- ii.mark_jump ();
-+ if (ANY_RETURN_P(PATTERN (insn)))
-+ continue;
-
-- rtx pattern = PATTERN (insn);
-- if (GET_CODE(pattern) == PARALLEL)
-+ ii.mark_jump ();
-+ if (jump_table)
- {
-- /*
-- * Use the jump_table_data and add all to the lookup
-- */
-- if (jump_table == 0)
-+ if (XEXP(jump_table, 0) != insn)
- {
-- // still allow if_then_else inside a parallel insn
-- rtx ite = XVECEXP(pattern, 0, 0);
-- if (XEXP(ite, 0) != pc_rtx || GET_CODE(XEXP(ite, 1)) != IF_THEN_ELSE)
-+ if (be_very_verbose)
- {
- debug_rtx (insn);
-- return 1; // do not optimize.
-+ debug_rtx (jump_table);
- }
-- rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-- label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ result = E_JUMP_TABLE_MISMATCH;
-+ jump_table = 0;
-+ continue;
- }
-- else if (XEXP(jump_table, 0) != insn)
-+
-+ // -> jump_table_data
-+ rtx table = PATTERN (XEXP(jump_table, 1));
-+ if (GET_CODE(table) == ADDR_DIFF_VEC || GET_CODE(table) == ADDR_VEC)
- {
-- debug_rtx (insn);
-- return 2;
-+ int k = GET_CODE(table) == ADDR_DIFF_VEC;
-+ for (int j = 0; j < XVECLEN(table, k); ++j)
-+ {
-+ rtx ref = XVECEXP(table, k, j);
-+ if (!LABEL_REF_NONLOCAL_P(ref))
-+ {
-+ rtx label = XEXP(ref, 0);
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ }
-+ }
- }
- else
- {
-- // -> jump_table_data
-- rtx table = PATTERN (XEXP(jump_table, 1));
-- for (int j = 0; j < XVECLEN(table, 1); ++j)
-+ if (be_very_verbose)
- {
-- rtx ref = XVECEXP(table, 1, j);
-- rtx label = XEXP(ref, 0);
-- label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ debug_rtx (insn);
-+ debug_rtx (jump_table);
- }
-+ result = E_JUMP_GOTO_LABEL;
-+ jump_table = 0;
-+ continue;
- }
- jump_table = 0;
- }
- else
- {
- rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ if (!label)
-+ {
-+ if (be_very_verbose)
-+ debug_rtx (insn);
-+ result = E_NO_JUMP_LABEL;
-+ continue;
-+ }
- label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
- }
--
- }
- else if (LABEL_P(insn))
- {
- ii.mark_label ();
-+ jump_table = 0;
- }
- else if (CALL_P(insn))
- {
-@@ -1468,7 +1488,7 @@ update_insns ()
- update_insn2index ();
- update_insn_infos ();
-
-- return 0;
-+ return result;
- }
-
- /* convert the lowest set bit into a register number. */
-@@ -2953,7 +2973,7 @@ opt_absolute (void)
- {
- insn_info & jj = infos[j];
- /* TODO: continue also at jump target */
-- if (jj.is_jump())
-+ if (jj.is_jump ())
- continue;
- /* TODO: check if label is visited only from jump targets from herein. then the label is ok. */
- if (jj.is_label ())
-@@ -3159,60 +3179,59 @@ namespace
- if (be_very_verbose)
- log ("ENTER\n");
-
-- for (;;)
-+ unsigned r = update_insns ();
-+ if (!r)
- {
-- int done = 1;
-- int r = update_insns ();
-- if (r)
-+ for (;;)
- {
-- if (be_verbose)
-- log ("no bbb optimization code %d\n", r);
-- return 0;
-- }
-- if (do_opt_strcpy && opt_strcpy ())
-- done = 0, update_insns ();
-+ int done = 1;
-+ if (do_opt_strcpy && opt_strcpy ())
-+ done = 0, update_insns ();
-
-- if (do_commute_add_move && opt_commute_add_move ())
-- done = 0, update_insns ();
-+ if (do_commute_add_move && opt_commute_add_move ())
-+ done = 0, update_insns ();
-
-- if (do_propagate_moves && opt_propagate_moves ())
-- done = 0, update_insns ();
-+ if (do_propagate_moves && opt_propagate_moves ())
-+ done = 0, update_insns ();
-
-- if (do_const_cmp_to_sub && opt_const_cmp_to_sub ())
-- done = 0, update_insns ();
-+ if (do_const_cmp_to_sub && opt_const_cmp_to_sub ())
-+ done = 0, update_insns ();
-
-- if (do_merge_add && opt_merge_add ())
-- done = 0;
-+ if (do_merge_add && opt_merge_add ())
-+ done = 0;
-
-- if (do_elim_dead_assign && opt_elim_dead_assign ())
-- done = 0, update_insns ();
-+ if (do_elim_dead_assign && opt_elim_dead_assign ())
-+ done = 0, update_insns ();
-
-- if (do_absolute && opt_absolute ())
-- done = 0;
-+ if (do_absolute && opt_absolute ())
-+ done = 0;
-
-- if (do_bb_reg_rename)
-- {
-- while (opt_reg_rename ())
-+ if (do_bb_reg_rename)
- {
-- update_insns ();
-- done = 0;
-+ while (opt_reg_rename ())
-+ {
-+ update_insns ();
-+ done = 0;
-+ }
- }
-- }
-
-- if (done)
-- break;
-- }
-+ if (done)
-+ break;
-+ }
-
-- if (do_shrink_stack_frame)
-- {
-- if (opt_shrink_stack_frame ())
-- update_insns ();
-+ if (do_shrink_stack_frame)
-+ {
-+ if (opt_shrink_stack_frame ())
-+ update_insns ();
-+ }
- }
-+ if (r && be_verbose)
-+ log ("no bbb optimization code %d\n", r);
-
- if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
- dump_insns ("bbb", strchr (string_bbb_opts, 'X'));
-
-- return 0;
-+ return r;
- }
-
- } // anon namespace
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 9166b91a69eb..a79b5cddd91b 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -39,6 +39,7 @@
- #include "target.h"
- #include "diagnostic-core.h"
- #include "langhooks.h"
-+#include "function.h"
- #include "config/m68k/amigaos.h"
-
- //#define MYDEBUG 1
-@@ -50,7 +51,6 @@
-
- //int amiga_declare_object;
-
--
- #if 0
- static int amigaos_put_in_text (tree);
- static rtx gen_stack_management_call (rtx, rtx, const char *);
-@@ -436,24 +436,18 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- if (!next_param && TREE_VALUE (param) != void_type_node)
- cum->num_of_regs = 0;
- }
--
-- /* check for return values passed in a0 */
-- if (cum->num_of_regs)
-- {
-- tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-- int sz = type ? TREE_INT_CST_LOW(type) : 0;
-- if (sz > 64) /* mark a0 as already used. */
-- cum->regs_already_used |= 1 << 8;
-- }
- }
-
-- //#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
-+#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
+diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
+new file mode 100644
+index 000000000000..3f3aafc5f254
+--- /dev/null
++++ gcc/config/m68k/m68kamigaos.h
+@@ -0,0 +1,760 @@
++/* m68kelf support, derived from m68kv4.h */
+
-+ if (fntype && DECL_STATIC_CHAIN(fntype))
-+ cum->regs_already_used |= (1 << STATIC_CHAIN_REGNUM);
-
- if (fntype)
- cum->formal_type = TYPE_ARG_TYPES(fntype);
-@@ -463,9 +457,8 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- DPRINTF(("1amigaos_init_cumulative_args %p -> %d\r\n", cum, cum->num_of_regs));
- }
-
--
- int
--amigaos_function_arg_reg(unsigned regno)
-+amigaos_function_arg_reg (unsigned regno)
- {
- return (mycum.regs_already_used & (1 << regno)) != 0;
- }
-@@ -802,20 +795,22 @@ amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_U
- #else
- extern void
- amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
--{
-- if (0 == strncmp(".text", name, 5))
-+ {
-+ if (0 == strncmp(".text", name, 5))
- name = ".text";
-
-- if (0 == strncmp("section ", name, 8)) {
-+ if (0 == strncmp("section ", name, 8))
-+ {
- // fprintf (asm_out_file, "\t.section\t%s\n", name);
-- fprintf (asm_out_file, "\t%s\n", name);
-- } else {
-- fprintf (asm_out_file, "\tsection %s\n", name);
-+ fprintf (asm_out_file, "\t%s\n", name);
-+ }
-+ else
-+ {
-+ fprintf (asm_out_file, "\tsection %s\n", name);
-+ }
- }
--}
- #endif
-
--
- /* Baserel support. */
-
- /**
-@@ -846,3 +841,22 @@ read_only_operand (rtx operand)
- return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P(operand);
- return 1;
- }
++/* Target definitions for GNU compiler for mc680x0 running AmigaOs
++ Copyright (C) 1991-2016 Free Software Foundation, Inc.
+
-+rtx
-+amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED)
-+{
-+ if (fntype && aggregate_value_p (TREE_TYPE(fntype), fntype))
-+ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
++ Written by Ron Guilmette (rfg@netcom.com) and Fred Fish (fnf@cygnus.com).
+
-+ return 0;
-+}
++This file is part of GCC.
+
-+rtx
-+amigaos_static_chain_rtx (const_tree fntype, bool incoming ATTRIBUTE_UNUSED)
-+{
-+ if (fntype && DECL_STATIC_CHAIN(fntype))
-+ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
++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 3, or (at your option)
++any later version.
+
-+ return 0;
-+}
++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.
+
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 284328683c37..c564c3f2db67 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -466,3 +466,14 @@ amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
- && GET_CODE(XEXP(XEXP(XEXP(x, 0), 1), 0)) == UNSPEC \
- )
-
-+#undef TARGET_STRUCT_VALUE_RTX
-+#define TARGET_STRUCT_VALUE_RTX amigaos_struct_value_rtx
-+rtx
-+amigaos_struct_value_rtx(tree fntype,
-+ int incoming ATTRIBUTE_UNUSED);
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3. If not see
++<http://www.gnu.org/licenses/>. */
+
-+#undef TARGET_STATIC_CHAIN
-+#define TARGET_STATIC_CHAIN amigaos_static_chain_rtx
-+rtx
-+amigaos_static_chain_rtx(const_tree fntype,
-+ bool incoming ATTRIBUTE_UNUSED);
-
-From bade0e4a363da3d63371623f36c746e976e22a18 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 21 May 2017 07:23:52 +0200
-Subject: [PATCH 131/303] @B fix return reg to comply test cases
-
----
- gcc/DATESTAMP | 2 +-
- gcc/config/m68k/m68kamigaos.h | 5 ++++-
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 3f03e820cb0b..301f35608896 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170520
-+20170521
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index f636e397cfca..a81007bb15d5 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -264,7 +264,10 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- /* 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))
-+ ((N) == D0_REG || (TARGET_68881 && (N) == FP0_REG))
++#ifndef TARGET_AMIGA
++#define TARGET_AMIGA 1
++#endif
+
-+// see 930623-1.c
-+// ((N) == D0_REG || (N) == A0_REG || (TARGET_68881 && (N) == FP0_REG))
-
- /* Inform the program which CPU we compile for. */
-
-
-From 3401ac796cd87583972c39b6ab730bf5faead050 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 22 May 2017 20:41:51 +0200
-Subject: [PATCH 132/303] @R use a dynamic static_chain register to avoid
- clashes with asm parameters
-
----
- gcc/config/m68k/amigaos.c | 33 +++++++++++++++++++++++++++++----
- 1 file changed, 29 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index a79b5cddd91b..8a92ef99db27 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -447,7 +447,11 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
- #endif
-
- if (fntype && DECL_STATIC_CHAIN(fntype))
-- cum->regs_already_used |= (1 << STATIC_CHAIN_REGNUM);
-+ {
-+ rtx reg = amigaos_static_chain_rtx (decl, 0);
-+ if (reg)
-+ cum->regs_already_used |= (1 << REGNO(reg));
-+ }
-
- if (fntype)
- cum->formal_type = TYPE_ARG_TYPES(fntype);
-@@ -852,10 +856,31 @@ amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED)
- }
-
- rtx
--amigaos_static_chain_rtx (const_tree fntype, bool incoming ATTRIBUTE_UNUSED)
-+amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
- {
-- if (fntype && DECL_STATIC_CHAIN(fntype))
-- return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
-+ if (!decl || !DECL_STATIC_CHAIN(decl))
-+ return 0;
++#define HAS_INIT_SECTION
+
-+ tree fntype = TREE_TYPE(decl);
++#ifndef SWBEG_ASM_OP
++#define SWBEG_ASM_OP "\t.swbeg\t"
++#endif
+
-+ unsigned used = 0;
++#ifdef TARGET_AMIGAOS_VASM
++#undef ASM_STABS_OP
++#define ASM_STABS_OP "|\t.stabs\t"
+
-+ for (tree formal_type = TYPE_ARG_TYPES(fntype); formal_type; formal_type = TREE_CHAIN(formal_type))
-+ {
-+ tree asmtree = TYPE_ATTRIBUTES(formal_type);
-+ if (!asmtree || strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-+ continue;
++#undef ASM_STABD_OP
++#define ASM_STABD_OP "|\t.stabd\t"
+
-+ unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-+ used |= 1 << regno;
-+ }
++#undef ASM_STABN_OP
++#define ASM_STABN_OP "|\t.stabn\t"
++#endif
+
-+ if (!(used & (1 << 9)))
-+ return gen_rtx_REG (Pmode, 9);
-+ if (!(used & (1 << 10)))
-+ return gen_rtx_REG (Pmode, 10);
-+ if (!(used & (1 << 11)))
-+ return gen_rtx_REG (Pmode, 11);
-
- return 0;
- }
-
-From 74d34b98a82894145e0021ed0fc00592210413d7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 23 May 2017 22:22:26 +0200
-Subject: [PATCH 133/303] @B fix function flow scanning
-
----
- gcc/bbb-opts.c | 95 +++++++++++++++++++++++++++-------------------------------
- 1 file changed, 44 insertions(+), 51 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 848c18e3be52..a06f1577fb94 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -155,12 +155,15 @@ class insn_info
- int src_intval;
- unsigned src_mem_addr;
-
-+ bool visited;
++#undef PIC_REG
++#define PIC_REG 12
+
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
- (rtx_code) 0), src_ee (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (
-- 0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (0)
-+ 0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (0), visited (
-+ false)
- {
- }
-
-@@ -408,14 +411,6 @@ class insn_info
- return proepi;
- }
-
-- inline void
-- reset ()
-- {
-- use = 0;
-- def = 0;
-- hard = 0;
-- }
--
- inline void
- reset_flags ()
- {
-@@ -574,34 +569,6 @@ class insn_info
- return *this;
- }
-
--#if 0
-- inline insn_info
-- operator | (insn_info const & o) const
-- {
-- insn_info t;
-- t.use = use | o.use;
-- t.def = def | o.def;
-- t.hard = hard | o.hard;
-- return t;
-- }
--
-- inline bool
-- operator == (insn_info const & o)
-- {
-- return use == o.use;
-- }
--
-- inline insn_info
-- operator ~ () const
-- {
-- insn_info t;
-- t.use = ~use;
-- t.def = ~def;
-- t.hard = ~hard;
-- return t;
-- }
--#endif
--
- inline insn_info &
- make_hard ()
- {
-@@ -628,6 +595,18 @@ class insn_info
- return true;
- }
-
-+ inline bool
-+ visit () const
-+ {
-+ return visited;
-+ }
++#undef FRAME_POINTER_REGNUM
++#define FRAME_POINTER_REGNUM 13
+
-+ inline void
-+ mark_visited ()
-+ {
-+ visited = true;
-+ }
++#undef M68K_REGNAME
++#define M68K_REGNAME(r) ( \
++ ( ((r) == FRAME_POINTER_REGNUM) \
++ && frame_pointer_needed) ? \
++ M68K_FP_REG_NAME : reg_names[(r)])
+
- void
- scan ();
-
-@@ -959,6 +938,9 @@ typedef std::multimap<int, rtx_insn *>::iterator l2j_iterator;
- static std::map<rtx_insn *, insn_info *> insn2index;
- typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
-
-+static std::set<unsigned> returns;
-+typedef std::set<unsigned>::iterator su_iterator;
+
- static insn_info * info0;
- static unsigned usable_regs;
-
-@@ -1148,6 +1130,7 @@ clear (void)
- label2jump.clear ();
- insn2index.clear ();
- infos.clear ();
-+ returns.clear ();
- }
-
- /*
-@@ -1256,11 +1239,14 @@ dump_insns (char const * name, bool all)
- static void
- update_insn_infos (void)
- {
-- /* own analyze reg life */
-+ /* add all return (jump outs) and start analysis there. */
- std::vector<std::pair<unsigned, insn_info> > todo;
-- todo.push_back (std::make_pair (infos.size () - 1, insn_info ()));
-+ for (su_iterator i = returns.begin (); i != returns.end (); ++i)
-+ todo.push_back (std::make_pair (*i, insn_info ()));
+
-+ if (todo.begin () == todo.end ())
-+ todo.push_back (std::make_pair (infos.size () - 1, insn_info ()));
-
-- int pass = 0;
- while (!todo.empty ())
- {
- std::pair<unsigned, insn_info> p = *todo.rbegin ();
-@@ -1270,17 +1256,18 @@ update_insn_infos (void)
-
- for (int pos = p.first; pos >= 0; --pos)
- {
-- rtx_insn * insn = infos[pos].get_insn ();
-+ insn_info & pp = infos[pos];
-+ rtx_insn * insn = pp.get_insn ();
- /* can be NULL as used in opt_shrink_stack_frame(). */
- if (!insn)
- continue;
-
- /* no new information -> break. */
-- if (pass && infos[pos].contains (ii))
-+ if (pp.in_proepi () == 0 && pp.visit () && pp.contains (ii))
- break;
-
- ii.clear_hard_def ();
-- ii.merge (infos[pos]);
-+ ii.merge (pp);
-
- if (LABEL_P(insn))
- {
-@@ -1295,6 +1282,8 @@ update_insn_infos (void)
- continue;
- }
-
-+ pp.mark_visited ();
++/* Here are three prefixes that are used by asm_fprintf to
++ facilitate customization for alternate assembler syntaxes.
++ Machines with no likelihood of an alternate syntax need not
++ define these and need not use asm_fprintf. */
+
- rtx pattern = PATTERN (insn);
- insn_info use (insn);
- use.scan ();
-@@ -1304,9 +1293,11 @@ update_insn_infos (void)
- }
- else if (JUMP_P(insn))
- {
-- if (ANY_RETURN_P(pattern))
-+ if (pos != p.first)
- {
-- ii.reset ();
-+ su_iterator k = returns.find (pos);
-+ if (k != returns.end ())
-+ break;
- }
- }
- else if (GET_CODE (pattern) == USE || GET_CODE (pattern) == CLOBBER)
-@@ -1330,10 +1321,9 @@ update_insn_infos (void)
- use.make_hard ();
-
- ii.merge (use);
-- infos[pos].update (ii);
-+ pp.update (ii);
- ii.updateWith (use);
- }
-- ++pass;
- }
-
- /* fill the mask of general used regs. */
-@@ -1389,10 +1379,13 @@ update_insns ()
-
- if (JUMP_P(insn))
- {
-- inproepilogue = 0;
--
-- if (ANY_RETURN_P(PATTERN (insn)))
-- continue;
-+ if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
-+ {
-+ returns.insert (infos.size () - 1);
-+ inproepilogue = 0;
-+ if (ANY_RETURN_P(PATTERN (insn)))
-+ continue;
-+ }
-
- ii.mark_jump ();
- if (jump_table)
-
-From b1334e77f8e493eaeb362392f035711d06484be7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 23 May 2017 22:22:44 +0200
-Subject: [PATCH 134/303] @B fix static_chain register handling
-
----
- gcc/config/m68k/amigaos.c | 24 ++++++++++++------------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 8a92ef99db27..dc2f2ac74369 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -602,7 +602,6 @@ amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree typ
- void
- amiga_emit_regparm_clobbers (void)
- {
-- rtx sp = gen_raw_REG (Pmode, 15);
- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- if (mycum.regs_already_used & (1 << i))
- {
-@@ -861,19 +860,18 @@ amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
- if (!decl || !DECL_STATIC_CHAIN(decl))
- return 0;
-
-- tree fntype = TREE_TYPE(decl);
--
- unsigned used = 0;
-+ tree fntype = TREE_TYPE(decl);
-+ if (fntype)
-+ for (tree formal_type = TYPE_ARG_TYPES(fntype); formal_type; formal_type = TREE_CHAIN(formal_type))
-+ {
-+ tree asmtree = TYPE_ATTRIBUTES(TREE_VALUE(formal_type));
-+ if (!asmtree || strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-+ continue;
-
-- for (tree formal_type = TYPE_ARG_TYPES(fntype); formal_type; formal_type = TREE_CHAIN(formal_type))
-- {
-- tree asmtree = TYPE_ATTRIBUTES(formal_type);
-- if (!asmtree || strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-- continue;
--
-- unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-- used |= 1 << regno;
-- }
-+ unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-+ used |= 1 << regno;
-+ }
-
- if (!(used & (1 << 9)))
- return gen_rtx_REG (Pmode, 9);
-@@ -881,6 +879,8 @@ amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
- return gen_rtx_REG (Pmode, 10);
- if (!(used & (1 << 11)))
- return gen_rtx_REG (Pmode, 11);
-+ if (!(used & (1 << 14)))
-+ return gen_rtx_REG (Pmode, 14);
-
- return 0;
- }
-
-From 5b9f0616bb8d5bf7cca7daaa9b5cd4056e0e6f9e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 24 May 2017 16:27:49 +0200
-Subject: [PATCH 135/303] @B fix stack frame shrinking
-
----
- gcc/bbb-opts.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 208 insertions(+), 26 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index a06f1577fb94..43bcf138fc20 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -157,13 +157,18 @@ class insn_info
-
- bool visited;
-
-+ int sp_offset;
++/* The prefix for register names. Note that REGISTER_NAMES
++ is supposed to include this prefix. Also note that this is NOT an
++ fprintf format string, it is a literal string */
+
-+ int dst_autoinc;
-+ int src_autoinc;
++#undef REGISTER_PREFIX
++#define REGISTER_PREFIX ""
+
- public:
- insn_info (rtx_insn * i = 0, int p = 0) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
- (rtx_code) 0), src_ee (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (
- 0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (0), visited (
-- false)
-+ false), sp_offset (0), dst_autoinc (0), src_autoinc (0)
- {
- }
-
-@@ -414,6 +419,8 @@ class insn_info
- inline void
- reset_flags ()
- {
-+ label = false;
-+ jump = false;
- compare = false;
- dst_mem = false;
- src_mem = false;
-@@ -435,6 +442,21 @@ class insn_info
-
- src_intval = 0;
- src_mem_addr = 0;
++/* The prefix for local (compiler generated) labels.
++ These labels will not appear in the symbol table. */
+
-+ dst_autoinc = 0;
-+ src_autoinc = 0;
-+ }
++#undef LOCAL_LABEL_PREFIX
++#ifndef TARGET_AMIGAOS_VASM
++#define LOCAL_LABEL_PREFIX "."
++#else
++#define LOCAL_LABEL_PREFIX "_."
++#endif
+
-+ inline int
-+ get_src_autoinc () const
-+ {
-+ return src_autoinc;
-+ }
++/* The prefix to add to user-visible assembler symbols. */
+
-+ inline int
-+ get_dst_autoinc () const
-+ {
-+ return dst_autoinc;
- }
-
- inline bool
-@@ -595,8 +617,20 @@ class insn_info
- return true;
- }
-
-+ inline int
-+ get_sp_offset () const
-+ {
-+ return sp_offset;
-+ }
++#undef USER_LABEL_PREFIX
++#define USER_LABEL_PREFIX "_"
+
-+ inline void
-+ set_sp_offset (int sp)
-+ {
-+ sp_offset = sp;
-+ }
++/* config/m68k.md has an explicit reference to the program counter,
++ prefix this by the register prefix. */
+
- inline bool
-- visit () const
-+ is_visited () const
- {
- return visited;
- }
-@@ -607,6 +641,12 @@ class insn_info
- visited = true;
- }
-
-+ inline void
-+ clear_visited ()
-+ {
-+ visited = false;
-+ }
++#ifndef TARGET_AMIGAOS_VASM
++#define ASM_RETURN_CASE_JUMP \
++ do { \
++ return "jmp %%pc@(2,%0:w)"; \
++ } while (0)
++#else
++#define ASM_RETURN_CASE_JUMP \
++ do { \
++ return "jmp (2,pc,%0.w)"; \
++ } while (0)
++#endif
+
- void
- scan ();
-
-@@ -770,6 +810,12 @@ insn_info::fledder (rtx set)
- {
- dst_mem = true;
- rtx mem = XEXP(dst, 0);
++/* This is how to output an assembler line that says to advance the
++ location counter to a multiple of 2**LOG bytes. */
+
-+ if (GET_CODE(mem) == POST_INC)
-+ dst_autoinc = 1, mem = XEXP(mem, 0);
-+ else if (GET_CODE(mem) == PRE_DEC)
-+ dst_autoinc = -1, mem = XEXP(mem, 0);
++#ifndef TARGET_AMIGAOS_VASM
++#ifndef ALIGN_ASM_OP
++#define ALIGN_ASM_OP "\t.align\t"
++#endif
++#else
++#define ALIGN_ASM_OP "\talign\t"
++#endif
+
- if (REG_P(mem))
- dst_mem_reg = mem;
- else if (GET_CODE(mem) == CONST_INT)
-@@ -831,6 +877,12 @@ insn_info::fledder (rtx set)
- {
- src_mem = true;
- rtx mem = XEXP(src, 0);
++#undef ASM_OUTPUT_ALIGN
++#ifndef TARGET_AMIGAOS_VASM
++#define ASM_OUTPUT_ALIGN(FILE,LOG) \
++do { \
++ if ((LOG) > 0) \
++ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, 1 << (LOG)); \
++} while (0)
++#else
++#define ASM_OUTPUT_ALIGN(FILE,LOG) \
++do { \
++ if ((LOG) > 0) \
++ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, (LOG)); \
++} while (0)
++#endif
+
-+ if (GET_CODE(mem) == POST_INC)
-+ src_autoinc = 1, mem = XEXP(mem, 0);
-+ else if (GET_CODE(mem) == PRE_DEC)
-+ src_autoinc = -1, mem = XEXP(mem, 0);
-+
- if (REG_P(mem))
- src_mem_reg = mem;
- else if (GET_CODE(mem) == CONST_INT)
-@@ -932,10 +984,15 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- static std::vector<insn_info> infos;
- typedef std::vector<insn_info>::iterator insn_info_iterator;
-
-+// insn->u2.insn_uid -> rtx_insn *
- static std::multimap<int, rtx_insn *> label2jump;
- typedef std::multimap<int, rtx_insn *>::iterator l2j_iterator;
-
--static std::map<rtx_insn *, insn_info *> insn2index;
-+// index -> index
-+static std::multimap<unsigned, unsigned> jump2label;
-+typedef std::multimap<unsigned, unsigned>::iterator j2l_iterator;
++#if 0
++extern int amiga_declare_object;
+
-+static std::map<rtx_insn *, insn_info *> insn2info;
- typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
-
- static std::set<unsigned> returns;
-@@ -948,16 +1005,31 @@ static void
- update_insn2index ()
- {
- infos.reserve (infos.size () * 8 / 7 + 2);
-- insn2index.clear ();
-+ insn2info.clear ();
- /* needs a separate pass since the insn_infos require fixed addresses for ->get_index() */
- for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & ii = infos[i];
-- insn2index.insert (std::make_pair (ii.get_insn (), &ii));
-+ insn2info.insert (std::make_pair (ii.get_insn (), &ii));
- }
- info0 = &infos[0];
- }
-
-+static void
-+update_label2jump ()
-+{
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ insn2info.insert (std::make_pair (ii.get_insn (), &ii));
++#define ASM_DECLARE_OBJECT_NAME(FILE,NAME,DECL) \
++if (!DECL_INITIAL (DECL) || \
++ initializer_zerop (DECL_INITIAL (decl))) \
++ { \
++ amiga_declare_object = 1; \
++ fprintf ((FILE), ".comm\t%s,", NAME); \
++ } \
++else \
++ASM_OUTPUT_LABEL (FILE, NAME)
+
-+ if (ii.is_label ())
-+ for (l2j_iterator i = label2jump.find (ii.get_insn ()->u2.insn_uid), k = i;
-+ i != label2jump.end () && i->first == k->first; ++i)
-+ jump2label.insert (std::make_pair (insn2info.find (i->second)->second->get_index (), index));
-+ }
-+}
++#undef ASM_OUTPUT_SKIP
++#define ASM_OUTPUT_SKIP(FILE,SIZE) \
++if (amiga_declare_object) \
++ fprintf (FILE, "%u\n", (int)(SIZE)); \
++else \
++ fprintf (FILE, "\t.skip %u\n", (int)(SIZE)); \
++amiga_declare_object = 0
++#endif
+
- int
- insn_info::get_index () const
- {
-@@ -986,7 +1058,7 @@ insn_info::plus_to_move (rtx_insn * newinsn)
- insn = newinsn;
- src_op = (rtx_code) 0;
- src_reg = XEXP(PATTERN (newinsn), 1);
-- insn2index.insert (std::make_pair (insn, this));
-+ insn2info.insert (std::make_pair (insn, this));
- // usage flags did not change
- }
-
-@@ -997,8 +1069,8 @@ insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
-
- std::swap (*this, ii);
-
-- insn2index.insert (std::make_pair (insn, this));
-- insn2index.insert (std::make_pair (ii.insn, &ii));
-+ insn2info.insert (std::make_pair (insn, this));
-+ insn2info.insert (std::make_pair (ii.insn, &ii));
-
- // usage flags did not change
- }
-@@ -1065,7 +1137,6 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- unsigned offset = addr - base;
- if (offset <= 0x7ffe)
- {
-- rtx olddst = dst;
- if (base == addr)
- dst = gen_rtx_MEM (mode, reg);
- else
-@@ -1119,7 +1190,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
-
- mark_use (regno);
-
-- insn2index.insert (std::make_pair (insn, this));
-+ insn2info.insert (std::make_pair (insn, this));
- }
- /*
- * Reset collected data.
-@@ -1128,7 +1199,8 @@ static void
- clear (void)
- {
- label2jump.clear ();
-- insn2index.clear ();
-+ jump2label.clear ();
-+ insn2info.clear ();
- infos.clear ();
- returns.clear ();
- }
-@@ -1160,8 +1232,8 @@ void
- append_reg_usage (FILE * f, rtx_insn * insn)
- {
-
-- i2i_iterator i = insn2index.find (insn);
-- if (i == insn2index.end ())
-+ i2i_iterator i = insn2info.find (insn);
-+ if (i == insn2info.end ())
- return;
-
- insn_info & ii = *i->second;
-@@ -1263,7 +1335,7 @@ update_insn_infos (void)
- continue;
-
- /* no new information -> break. */
-- if (pp.in_proepi () == 0 && pp.visit () && pp.contains (ii))
-+ if (pp.in_proepi () == 0 && pp.is_visited () && pp.contains (ii))
- break;
-
- ii.clear_hard_def ();
-@@ -1275,8 +1347,8 @@ update_insn_infos (void)
- for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
- i != label2jump.end () && i->first == k->first; ++i)
- {
-- i2i_iterator j = insn2index.find (i->second);
-- if (j != insn2index.end ())
-+ i2i_iterator j = insn2info.find (i->second);
-+ if (j != insn2info.end ())
- todo.push_back (std::make_pair (j->second->get_index (), ii));
- }
- continue;
-@@ -1293,11 +1365,14 @@ update_insn_infos (void)
- }
- else if (JUMP_P(insn))
- {
-- if (pos != p.first)
-+ if ((unsigned) pos != p.first)
- {
- su_iterator k = returns.find (pos);
- if (k != returns.end ())
-- break;
-+ {
-+ pp.clear_visited ();
-+ break;
-+ }
- }
- }
- else if (GET_CODE (pattern) == USE || GET_CODE (pattern) == CLOBBER)
-@@ -1350,7 +1425,7 @@ update_insn_infos (void)
-
- enum AbortCodes
- {
-- E_OK, E_NO_JUMP_LABEL, E_JUMP_TABLE_MISMATCH, E_JUMP_GOTO_LABEL
-+ E_OK, E_NO_JUMP_LABEL, E_JUMP_TABLE_MISMATCH, E_JUMP_GOTO_LABEL, E_SP_MISMATCH
- };
-
- /*
-@@ -1598,8 +1673,8 @@ opt_reg_rename (void)
- for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
- i != label2jump.end () && i->first == k->first; ++i)
- {
-- i2i_iterator j = insn2index.find (i->second);
-- if (j == insn2index.end ())
-+ i2i_iterator j = insn2info.find (i->second);
-+ if (j == insn2info.end ())
- continue;
-
- unsigned start = j->second->get_index ();
-@@ -1647,8 +1722,8 @@ opt_reg_rename (void)
- /* follow jump and/or next insn. */
- if (JUMP_P(insn))
- {
-- i2i_iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(insn));
-- if (j == insn2index.end ())
-+ i2i_iterator j = insn2info.find ((rtx_insn *) JUMP_LABEL(insn));
-+ if (j == insn2info.end ())
- {
- /* whoops - label not found. */
- mask = 0;
-@@ -2488,6 +2563,86 @@ opt_merge_add (void)
- return change_count;
- }
-
-+/* Update the insn_infos to 'know' the sp offset. */
-+static unsigned
-+track_sp ()
-+{
-+ // reset visited flags
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ ii.clear_visited ();
-+ ii.set_sp_offset (0);
-+ }
++/* Register in which address to store a structure value is passed to a
++ function. The default in m68k.h is a1. For m68k/SVR4 it is a0. */
+
-+ // add entry point
-+ std::vector<unsigned> todo;
-+ todo.push_back (0);
++#undef M68K_STRUCT_VALUE_REGNUM
++#define M68K_STRUCT_VALUE_REGNUM A0_REG
+
-+ while (todo.size () > 0)
-+ {
-+ unsigned startpos = todo[todo.size () - 1];
-+ todo.pop_back ();
++/* The static chain regnum defaults to a0, but we use that for
++ structure return, so have to use a1 for the static chain. */
+
-+ int sp_offset = infos[startpos].get_sp_offset ();
++#undef STATIC_CHAIN_REGNUM
++#define STATIC_CHAIN_REGNUM A1_REG
++#undef M68K_STATIC_CHAIN_REG_NAME
++#define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a1"
+
-+ for (unsigned index = startpos; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi ())
-+ continue;
++#ifndef TARGET_AMIGAOS_VASM
++#define ASM_COMMENT_START "|"
++#else
++#define ASM_COMMENT_START "|"
++#endif
+
-+ // already visited? sp_offset must match
-+ if (ii.is_visited ())
-+ {
-+ if (ii.get_sp_offset () != sp_offset)
-+ return E_SP_MISMATCH;
-+ break;
-+ }
++/* Define how the m68k registers should be numbered for Dwarf output.
++ The numbering provided here should be compatible with the native
++ SVR4 SDB debugger in the m68k/SVR4 reference port, where d0-d7
++ are 0-7, a0-a8 are 8-15, and fp0-fp7 are 16-23. */
+
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
-+ ii.set_sp_offset (sp_offset);
++#undef DBX_REGISTER_NUMBER
++#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
-+ // add all referred labels
-+ if (ii.is_jump ())
-+ {
-+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i)
-+ {
-+ insn_info & ll = infos[i->second];
-+ if (ll.is_visited () && ll.get_sp_offset () != sp_offset)
-+ return E_SP_MISMATCH;
++#if 0
++/* SVR4 m68k assembler is bitching on the `comm i,1,1' which askes for
++ 1 byte alignment. Don't generate alignment for COMMON seems to be
++ safer until we the assembler is fixed. */
++#undef ASM_OUTPUT_ALIGNED_COMMON
++/* Same problem with this one. */
++#undef ASM_OUTPUT_ALIGNED_LOCAL
++#endif
+
-+ ll.set_sp_offset (sp_offset);
-+ todo.push_back (i->second);
-+ }
-+ continue;
-+ }
++#undef ASM_OUTPUT_COMMON
++#undef ASM_OUTPUT_LOCAL
++#ifndef TARGET_AMIGAOS_VASM
++#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
++( fputs (".comm ", (FILE)), \
++ assemble_name ((FILE), (NAME)), \
++ fprintf ((FILE), ",%u\n", (int)(SIZE)))
++#else
++#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
++ ( switch_to_section (bss_section), \
++ fputs ("|.comm\n\tcnop 0,4\n", (FILE)), \
++ assemble_name ((FILE), (NAME)), \
++ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)), \
++ fputs ("\txdef ", (FILE)), \
++ assemble_name ((FILE), (NAME)), \
++ fprintf ((FILE), "\n"))
++#endif
+
-+ // is sp modified directly
-+ if (ii.is_dst_reg () && ii.get_dst_regno () == STACK_POINTER_REGNUM)
-+ {
-+ // handle sp = sp + const_int
-+ if (!ii.is_src_reg () || ii.get_src_regno () != STACK_POINTER_REGNUM || ii.get_src_op () != PLUS)
-+ return E_SP_MISMATCH;
++#ifndef TARGET_AMIGAOS_VASM
++#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
++( fputs (".lcomm ", (FILE)), \
++ assemble_name ((FILE), (NAME)), \
++ fprintf ((FILE), ",%u\n", (int)(SIZE)))
++#else
++#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
++( switch_to_section (bss_section), \
++ fputs ("|.lcomm\n\tcnop 0,4\n", (FILE)), \
++ assemble_name ((FILE), (NAME)), \
++ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)))
++#endif
+
-+ sp_offset = sp_offset + ii.get_src_intval ();
-+ continue;
-+ }
++/* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
++ keep switch tables in the text section. */
++
++#define JUMP_TABLES_IN_TEXT_SECTION 1
+
-+ // handle dst mem autoinc
-+ if (ii.is_dst_mem () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM && ii.get_dst_autoinc ())
-+ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_dst_autoinc ();
++/* In m68k svr4, using swbeg is the standard way to do switch
++ table. */
++#undef ASM_OUTPUT_BEFORE_CASE_LABEL
++#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
++ fprintf ((FILE), "%s&%d\n", SWBEG_ASM_OP, XVECLEN (PATTERN (TABLE), 1));
++/* end of stuff from m68kv4.h */
+
-+ // handle src mem autoinc
-+ if (ii.is_src_mem () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM && ii.get_src_autoinc ())
-+ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_src_autoinc ();
-+ }
-+ }
++#ifndef TARGET_AMIGAOS_VASM
++#undef BSS_SECTION_ASM_OP
++#define BSS_SECTION_ASM_OP "\t.bss"
++#else
++#define BSS_SECTION_ASM_OP "\tsection\tbss"
++#endif
+
-+ return 0;
-+}
++#ifndef TARGET_AMIGAOS_VASM
++#undef DATA_SECTION_ASM_OP
++#define DATA_SECTION_ASM_OP "\t.data"
++#else
++#define DATA_SECTION_ASM_OP "\tsection\tdata"
++#endif
+
- /**
- * 1. scan for all used registers.
- * 2. scan the stack from for omittable push/pop
-@@ -2517,6 +2672,11 @@ opt_shrink_stack_frame (void)
- if (!infos.size ())
- return 0;
-
-+ /* needed to track sp correctly. */
-+ update_label2jump ();
-+ if (track_sp ())
-+ return 0; // do nothing on stack errors
++#ifndef ASM_OUTPUT_ALIGNED_BSS
++#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
++ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
++#endif
+
- std::vector<int> a5pos;
-
- unsigned pos = 0;
-@@ -2875,6 +3035,14 @@ opt_shrink_stack_frame (void)
- rtx pattern = PATTERN (ii.get_insn ());
- if (ii.is_compare ())
- pattern = XEXP(pattern, 1);
-+
-+ // lea n(sp),ax
-+ if (ii.get_src_reg() && ii.get_src_regno () == STACK_POINTER_REGNUM && ii.get_src_op () == PLUS)
-+ {
-+ rtx src = XEXP(pattern, 1);
-+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), ii.get_src_intval () - adjust);
-+ }
+
- if (ii.is_src_mem () && ii.is_src_mem_plus () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM)
- {
- rtx src = XEXP(pattern, 1);
-@@ -2902,8 +3070,22 @@ opt_shrink_stack_frame (void)
- log ("(f) dropping unused frame pointer\n");
- for (std::vector<int>::reverse_iterator i = a5pos.rbegin (); i != a5pos.rend (); ++i)
- {
-- SET_INSN_DELETED(infos[*i].get_insn ());
-- infos.erase (infos.begin () + *i);
-+ unsigned index = *i;
-+ SET_INSN_DELETED(infos[index].get_insn ());
-+ while (index > 0 && infos[index].in_proepi () == 2)
-+ --index;
++/* Specs, switches. */
+
-+ insn_info & ii = infos[index];
-+ if (!ii.in_proepi ())
-+ {
-+ if (ii.get_sp_offset () != 0)
-+ {
-+ log ("(f) adjusting exit sp\n");
-+ rtx pattern = gen_rtx_SET(
-+ a7, gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT(SImode, - ii.get_sp_offset())));
-+ emit_insn_after (pattern, ii.get_insn ());
-+ }
-+ }
- }
-
- /* convert all parameter accesses via a5 into a7. */
-@@ -3157,7 +3339,7 @@ namespace
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
- be_very_verbose = strchr (string_bbb_opts, 'V');
-- be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v');
-+ be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v') || 1;
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-
-From 103cba07eca32f607fa4b9c6cce1ff757c9b97d4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 24 May 2017 16:28:36 +0200
-Subject: [PATCH 136/303] @D disable verbose
-
----
- gcc/bbb-opts.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 43bcf138fc20..9dff55129ae3 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3339,7 +3339,7 @@ namespace
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
- be_very_verbose = strchr (string_bbb_opts, 'V');
-- be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v') || 1;
-+ be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v');
-
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-
-From 3d84b641d630cd99c5ce14eeb42bc5307be3ffa8 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 24 May 2017 16:30:36 +0200
-Subject: [PATCH 137/303] @V bump date
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 301f35608896..8afbbd33cdaa 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170521
-+20170524
-
-From a2ab0f8a257f6900e89d574ab8adf366fbd3d4a7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 24 May 2017 20:06:02 +0200
-Subject: [PATCH 138/303] @B fix shrink stack frame - do not modify sp offsets
- in prologue/epilogue
-
----
- gcc/bbb-opts.c | 16 ++++++++++------
- 1 file changed, 10 insertions(+), 6 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 9dff55129ae3..bbbf02561fb4 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1239,13 +1239,14 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- insn_info & ii = *i->second;
-
- if (f != stderr)
-- fprintf (f, "\n\t\t\t\t\t\t|%c ", ii.is_stack () ? 's' : ' ');
-+ fprintf (f, "\n\t\t\t\t\t\t|%c ",
-+ ii.is_stack () ? 's' : ii.in_proepi () == 1 ? 'p' : ii.in_proepi () == 2 ? 'e' : ' ');
-
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j) || ii.is_def (j))
- {
- fprintf (f, ii.is_hard (j) ? "!" : " ");
-- fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse (j) ? "." : " ");
- fprintf (f, "d%d ", j);
- }
- else
-@@ -1255,7 +1256,7 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- if (ii.is_use (j) || ii.is_def (j))
- {
- fprintf (f, ii.is_hard (j) ? "!" : " ");
-- fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse (j) ? "." : " ");
- fprintf (f, "a%d ", j - 8);
- }
- else
-@@ -3032,12 +3033,15 @@ opt_shrink_stack_frame (void)
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-+ if (ii.in_proepi ())
-+ continue;
++/* 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'. */
+
- rtx pattern = PATTERN (ii.get_insn ());
- if (ii.is_compare ())
- pattern = XEXP(pattern, 1);
-
- // lea n(sp),ax
-- if (ii.get_src_reg() && ii.get_src_regno () == STACK_POINTER_REGNUM && ii.get_src_op () == PLUS)
-+ if (ii.get_src_reg () && ii.get_src_regno () == STACK_POINTER_REGNUM && ii.get_src_op () == PLUS)
- {
- rtx src = XEXP(pattern, 1);
- XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), ii.get_src_intval () - adjust);
-@@ -3049,13 +3053,13 @@ opt_shrink_stack_frame (void)
- rtx plus = XEXP(src, 0);
- if (ii.get_src_op ())
- plus = XEXP(plus, 0);
-- XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_src_mem_addr () - adjust);
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), ii.get_src_mem_addr () - adjust);
- }
-
- if (ii.is_dst_mem () && ii.is_dst_mem_plus () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM)
- {
- rtx plus = XEXP(XEXP(pattern, 0), 0);
-- XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_dst_intval () - adjust);
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), ii.get_dst_intval () - adjust);
- }
- }
- }
-
-From 948b24860fbecf6442f8d9dca3b932a951df57b1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 26 May 2017 12:53:30 +0200
-Subject: [PATCH 139/303] @B fix inserting exit sp correction, @B fix parallel
- pop if stack frame gets removed, @B fix patch only sp offsets referring to
- local vars/params
-
----
- gcc/DATESTAMP | 2 +-
- gcc/bbb-opts.c | 139 ++++++++++++++++++++++++++++++++++++++++++---------------
- 2 files changed, 103 insertions(+), 38 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 8afbbd33cdaa..4d8890e894e9 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170524
-+20170526
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index bbbf02561fb4..b716cf24a9a0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -111,6 +111,11 @@ log (char const * fmt, ...)
- return retval;
- }
-
-+enum proepis
-+{
-+ IN_CODE, IN_PROLOGUE, IN_EPILOGUE, IN_EPILOGUE_PARALLEL_POP
-+};
++#undef TARGET_OS_CPP_BUILTINS
++#define TARGET_OS_CPP_BUILTINS() \
++ do \
++ { \
++ builtin_define ("__chip=__attribute__((__chip__))"); \
++ builtin_define ("__fast=__attribute__((__fast__))"); \
++ builtin_define ("__far=__attribute__((__far__))"); \
++ builtin_define ("__saveds=__attribute__((__saveds__))"); \
++ builtin_define ("__interrupt=__attribute__((__interrupt__))"); \
++ builtin_define ("__stackext=__attribute__((__stackext__))"); \
++ builtin_define ("__regargs=__attribute__((__regparm__(2)))"); \
++ builtin_define ("__stdargs=__attribute__((__stkparm__))"); \
++ builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \
++ builtin_define_std ("amiga"); \
++ builtin_define_std ("amigaos"); \
++ builtin_define_std ("AMIGA"); \
++ builtin_define_std ("MCH_AMIGA"); \
++ builtin_assert ("system=amigaos"); \
++ } \
++ while (0)
+
- /* Information for each insn to detect alive registers. Enough for m68k.
- * Why a class? Maybe extend it for general usage.
- *
-@@ -126,7 +131,7 @@ class insn_info
- unsigned use; // bit set if registers are used in program flow
- unsigned def; // bit set if registers are defined here
-
-- int proepi; // 1 = in prologue, 2 = in epilogue, 0 = other
-+ enum proepis proepi;
-
- bool stack; // part of stack frame insns
-
-@@ -163,7 +168,7 @@ class insn_info
- int src_autoinc;
-
- public:
-- insn_info (rtx_insn * i = 0, int p = 0) :
-+ insn_info (rtx_insn * i = 0, enum proepis p = IN_CODE) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
- (rtx_code) 0), src_ee (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (
-@@ -416,6 +421,12 @@ class insn_info
- return proepi;
- }
-
-+ inline void
-+ set_proepi (enum proepis p)
-+ {
-+ proepi = p;
-+ }
++#if 0
++if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
++ builtin_define ("errno=(*ixemul_errno)"); \
+
- inline void
- reset_flags ()
- {
-@@ -784,6 +795,9 @@ insn_info::scan_rtx (rtx x)
- void
- insn_info::fledder (rtx set)
- {
-+ if (GET_CODE(set) == PARALLEL)
-+ return;
++#endif
+
- rtx dst = SET_DEST(set);
- rtx src = SET_SRC(set);
-
-@@ -1239,8 +1253,10 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- insn_info & ii = *i->second;
-
- if (f != stderr)
-- fprintf (f, "\n\t\t\t\t\t\t|%c ",
-- ii.is_stack () ? 's' : ii.in_proepi () == 1 ? 'p' : ii.in_proepi () == 2 ? 'e' : ' ');
-+ fprintf (f, "\n\t\t\t\t\t\t|");
++/* put return values in FPU build in FP0 Reg */
++#undef FUNCTION_VALUE_REGNO_P
++#define FUNCTION_VALUE_REGNO_P(N) \
++ ((N) == D0_REG || (TARGET_68881 && (N) == FP0_REG))
+
-+ fprintf (f, "%c ",
-+ ii.is_stack () ? 's' : ii.in_proepi () == IN_PROLOGUE ? 'p' : ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
-
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j) || ii.is_def (j))
-@@ -1336,7 +1352,7 @@ update_insn_infos (void)
- continue;
-
- /* no new information -> break. */
-- if (pp.in_proepi () == 0 && pp.is_visited () && pp.contains (ii))
-+ if (pp.in_proepi () == IN_CODE && pp.is_visited () && pp.contains (ii))
- break;
-
- ii.clear_hard_def ();
-@@ -1393,7 +1409,7 @@ update_insn_infos (void)
- }
-
- /* mark not renameable in prologue/epilogue. */
-- if (infos[pos].in_proepi ())
-+ if (infos[pos].in_proepi () != IN_CODE)
- use.make_hard ();
-
- ii.merge (use);
-@@ -1407,7 +1423,7 @@ update_insn_infos (void)
- for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & ii = infos[i];
-- if (ii.in_proepi () != 1)
-+ if (ii.in_proepi () != IN_PROLOGUE)
- break;
-
- zz.or_use (ii);
-@@ -1441,7 +1457,7 @@ update_insns ()
-
- clear ();
-
-- char inproepilogue = 1;
-+ enum proepis inproepilogue = IN_PROLOGUE;
- /* create a vector with relevant insn. */
- for (insn = get_insns (); insn; insn = next)
- {
-@@ -1458,7 +1474,7 @@ update_insns ()
- if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
- {
- returns.insert (infos.size () - 1);
-- inproepilogue = 0;
-+ inproepilogue = IN_CODE;
- if (ANY_RETURN_P(PATTERN (insn)))
- continue;
- }
-@@ -1548,9 +1564,9 @@ update_insns ()
- else if (NOTE_P(insn))
- {
- if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-- inproepilogue = 0;
-+ inproepilogue = IN_CODE;
- else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
-- inproepilogue = 2;
-+ inproepilogue = IN_EPILOGUE;
- }
- }
-
-@@ -2590,7 +2606,7 @@ track_sp ()
- for (unsigned index = startpos; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-- if (ii.in_proepi ())
-+ if (ii.in_proepi () != IN_CODE)
- continue;
-
- // already visited? sp_offset must match
-@@ -2624,7 +2640,7 @@ track_sp ()
- if (ii.is_dst_reg () && ii.get_dst_regno () == STACK_POINTER_REGNUM)
- {
- // handle sp = sp + const_int
-- if (!ii.is_src_reg () || ii.get_src_regno () != STACK_POINTER_REGNUM || ii.get_src_op () != PLUS)
-+ if (!ii.get_src_reg () || ii.get_src_regno () != STACK_POINTER_REGNUM || ii.get_src_op () != PLUS)
- return E_SP_MISMATCH;
-
- sp_offset = sp_offset + ii.get_src_intval ();
-@@ -2698,7 +2714,7 @@ opt_shrink_stack_frame (void)
- insn_info & ii = infos[pos];
- insn = ii.get_insn ();
-
-- if (ii.in_proepi () != 1)
-+ if (ii.in_proepi () != IN_PROLOGUE)
- break;
-
- rtx pattern = PATTERN (insn);
-@@ -2770,7 +2786,7 @@ opt_shrink_stack_frame (void)
- {
- while (pos < infos.size ())
- {
-- if (infos[pos].in_proepi ())
-+ if (infos[pos].in_proepi () != IN_CODE)
- break;
- ++pos;
- }
-@@ -2780,7 +2796,7 @@ opt_shrink_stack_frame (void)
- {
- insn_info & ii = infos[pos];
- insn = ii.get_insn ();
-- if (JUMP_P(insn) || LABEL_P(insn) || !ii.in_proepi ())
-+ if (JUMP_P(insn) || LABEL_P(insn) || ii.in_proepi () == IN_CODE)
- break;
-
- /* omit the frame pointer a5. */
-@@ -2831,7 +2847,7 @@ opt_shrink_stack_frame (void)
- for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & jj = infos[i];
-- if (jj.in_proepi ())
-+ if (jj.in_proepi () == IN_CODE)
- continue;
-
- ii.or_use (jj);
-@@ -2843,6 +2859,8 @@ opt_shrink_stack_frame (void)
-
- unsigned changed = 0;
- unsigned adjust = 0;
-+ unsigned regs_seen = 0;
-+ unsigned regs_total_size = 0;
- /* now all push/pop insns are in temp. */
- for (unsigned i = 0; i < infos.size (); ++i)
- {
-@@ -2861,6 +2879,11 @@ opt_shrink_stack_frame (void)
- if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
- continue;
-
-+ if (ii.in_proepi () == IN_EPILOGUE)
-+ ii.set_proepi (IN_EPILOGUE_PARALLEL_POP);
++// see 930623-1.c
++// ((N) == D0_REG || (N) == A0_REG || (TARGET_68881 && (N) == FP0_REG))
+
-+ regs_seen = 0;
-+ regs_total_size = 0;
- std::vector<rtx> regs;
- std::vector<rtx> clobbers;
- for (int j = 0; j < XVECLEN(pattern, 0); ++j)
-@@ -2884,15 +2907,20 @@ opt_shrink_stack_frame (void)
- if (i < prologueend)
- paramstart += 4;
- unsigned regbit = 1 << REGNO(reg);
++/* Inform the program which CPU we compile for. */
+
-+ ++regs_seen;
- if (freemask & regbit)
- {
- log (i < prologueend ? "(f) remove push for %s\n" : "(f) remove pop for %s\n",
- reg_names[REGNO(reg)]);
- if (i < prologueend)
-- adjust += 4;
-+ adjust += GET_MODE_SIZE(GET_MODE(reg));
- }
- else
-- regs.push_back (copy_reg (reg, -1));
-+ {
-+ regs_total_size += GET_MODE_SIZE(GET_MODE(reg));
-+ regs.push_back (copy_reg (reg, -1));
-+ }
- }
-
- /* add room for add.
-@@ -2901,10 +2929,9 @@ opt_shrink_stack_frame (void)
- * Otherwise a7 is used and with (a7)+ addressing.
- */
- int add1 = i < prologueend || !usea5 ? 1 : 0;
-- if ((int) regs.size () + add1 + (int) clobbers.size () < XVECLEN(pattern, 0) || regs.size () <= 2)
-+ if (regs.size () < regs_seen)
- {
-- log ("(f) shrinking stack frame from %d to %d\n", XVECLEN(pattern, 0) - add1 - clobbers.size (),
-- regs.size ());
-+ log ("(f) shrinking stack frame from %d to %d\n", regs_seen, regs.size ());
- if (regs.size () <= 2)
- {
- changed = 1;
-@@ -3033,7 +3060,7 @@ opt_shrink_stack_frame (void)
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-- if (ii.in_proepi ())
-+ if (ii.in_proepi () != IN_CODE)
- continue;
-
- rtx pattern = PATTERN (ii.get_insn ());
-@@ -3043,11 +3070,14 @@ opt_shrink_stack_frame (void)
- // lea n(sp),ax
- if (ii.get_src_reg () && ii.get_src_regno () == STACK_POINTER_REGNUM && ii.get_src_op () == PLUS)
- {
-- rtx src = XEXP(pattern, 1);
-- XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), ii.get_src_intval () - adjust);
-+ // touch only if above pushed parameters
-+ if (ii.get_src_intval () > -ii.get_sp_offset ())
-+ {
-+ rtx src = XEXP(pattern, 1);
-+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), ii.get_src_intval () - adjust);
-+ }
- }
--
-- if (ii.is_src_mem () && ii.is_src_mem_plus () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM)
-+ else if (ii.is_src_mem () && ii.is_src_mem_plus () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM)
- {
- rtx src = XEXP(pattern, 1);
- rtx plus = XEXP(src, 0);
-@@ -3076,19 +3106,18 @@ opt_shrink_stack_frame (void)
- {
- unsigned index = *i;
- SET_INSN_DELETED(infos[index].get_insn ());
-- while (index > 0 && infos[index].in_proepi () == 2)
++//#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)
++*/
+
-+ // move to last insn in epilogue
-+ while (index - 1 > 0 && infos[index - 1].in_proepi () >= IN_EPILOGUE)
- --index;
-
- insn_info & ii = infos[index];
-- if (!ii.in_proepi ())
-+ if (ii.get_sp_offset () != 0)
- {
-- if (ii.get_sp_offset () != 0)
-- {
-- log ("(f) adjusting exit sp\n");
-- rtx pattern = gen_rtx_SET(
-- a7, gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT(SImode, - ii.get_sp_offset())));
-- emit_insn_after (pattern, ii.get_insn ());
-- }
-+ log ("(f) adjusting exit sp\n");
-+ rtx pattern = gen_rtx_SET(a7,
-+ gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT(SImode, - ii.get_sp_offset())));
-+ emit_insn_before (pattern, ii.get_insn ());
- }
- }
-
-@@ -3097,7 +3126,43 @@ opt_shrink_stack_frame (void)
- {
- insn_info & ii = infos[i];
- if (ii.get_myuse () & (1 << FRAME_POINTER_REGNUM))
-- ii.a5_to_a7 (a7);
-+ {
-+ ii.a5_to_a7 (a7);
-+ if (regs_seen && ii.in_proepi () == IN_EPILOGUE_PARALLEL_POP)
-+ {
-+ // exit sp insn needs an +
-+ rtx pattern = PATTERN (ii.get_insn ());
-+ unsigned sz = XVECLEN(pattern, 0);
++/* When creating shared libraries, use different 'errno'. */
++#define CPP_IXEMUL_SPEC \
++ "%{!ansi:-Dixemul} -D__ixemul__ -D__ixemul " \
++ "%{malways-restore-a4:-Derrno=(*ixemul_errno)} " \
++ "%{mrestore-a4:-Derrno=(*ixemul_errno)}"
++#define CPP_LIBNIX_SPEC \
++ "-isystem %:sdk_root(libnix/include) " \
++ "%{!ansi:-Dlibnix} -D__libnix__ -D__libnix"
++#define CPP_CLIB2_SPEC \
++ "-isystem %:sdk_root(clib2/include) " \
++ "%{!ansi:-DCLIB2} -D__CLIB2__ -D__CLIB2"
+
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (sz + 1));
-+ unsigned n = 0;
-+ for (unsigned j = 0; j < sz; ++j)
-+ {
-+ rtx set = XVECEXP(pattern, 0, j);
-+ rtx reg = SET_DEST(set);
-+ rtx mem = SET_SRC(set);
-+ rtx plus = XEXP(mem, 0);
-+ if (n)
-+ {
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, n);
-+ }
-+ else
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ }
-+ n += GET_MODE_SIZE(GET_MODE(reg));
-+ XVECEXP(parallel, 0, j + 1) = set;
-+ }
++/* 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. */
+
-+ rtx a = copy_reg (a7, -1);
-+ a->frame_related = 1;
-+ rtx plus = gen_rtx_PLUS(SImode, a, gen_rtx_CONST_INT (SImode, regs_total_size));
-+ rtx set = gen_rtx_SET(a, plus);
-+ XVECEXP(parallel, 0, 0) = set;
-+ SET_INSN_DELETED(ii.get_insn ());
-+ ii.set_insn (emit_insn_after (parallel, ii.get_insn ()));
-+ }
-+ }
-
- ii.unset (FRAME_POINTER_REGNUM);
- }
-
-From 0c94ad510c11dbd020d66482ac4ef28857f86d2e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 26 May 2017 21:20:04 +0200
-Subject: [PATCH 140/303] @B fix flow recog loop
-
----
- gcc/bbb-opts.c | 50 +++++++++++++++++++++++++++++++++++---------------
- 1 file changed, 35 insertions(+), 15 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index b716cf24a9a0..6b1a6bb5f3c0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -177,6 +177,12 @@ class insn_info
- {
- }
-
-+ inline ptrdiff_t
-+ operator < (insn_info const & o) const
-+ {
-+ return this - &o;
-+ }
++#define CPP_SPEC \
++ "%{m68881:-D__HAVE_68881__} " \
++ "%{!ansi:" \
++ "%{m68020:-Dmc68020} " \
++ "%{mc68020:-Dmc68020} " \
++ "%{m68020-40:-Dmc68020} " \
++ "%{m68020-60:-Dmc68020} " \
++ "%{m68030:-Dmc68030} " \
++ "%{m68040:-Dmc68040} " \
++ "%{m68060:-Dmc68060}} " \
++ "%{m68020:-D__mc68020__ -D__mc68020} " \
++ "%{mc68020:-D__mc68020__ -D__mc68020} " \
++ "%{m68020-40:-D__mc68020__ -D__mc68020} " \
++ "%{m68020-60:-D__mc68020__ -D__mc68020} " \
++ "%{m68030:-D__mc68030__ -D__mc68030} " \
++ "%{m68040:-D__mc68040__ -D__mc68040} " \
++ "%{m68060:-D__mc68060__ -D__mc68060} " \
++ "%{noixemul:%(cpp_libnix)} " \
++ "%{mcrt=nix*:%(cpp_libnix)} " \
++ "%{mcrt=ixemul:%(cpp_ixemul)} " \
++ "%{mcrt=clib2:%(cpp_clib2)} " \
++ "%{!noixemul:%{!mcrt*:%(cpp_libnix)}}"
+
- int
- get_index () const;
-
-@@ -1329,21 +1335,20 @@ static void
- update_insn_infos (void)
- {
- /* add all return (jump outs) and start analysis there. */
-- std::vector<std::pair<unsigned, insn_info> > todo;
-+ std::set<unsigned> todo;
- for (su_iterator i = returns.begin (); i != returns.end (); ++i)
-- todo.push_back (std::make_pair (*i, insn_info ()));
-+ todo.insert (*i);
-
- if (todo.begin () == todo.end ())
-- todo.push_back (std::make_pair (infos.size () - 1, insn_info ()));
-+ todo.insert (infos.size () - 1);
-
- while (!todo.empty ())
- {
-- std::pair<unsigned, insn_info> p = *todo.rbegin ();
-- todo.pop_back ();
-+ int start = *todo.begin ();
-+ todo.erase (todo.begin ());
-+ insn_info ii = infos[start];
-
-- insn_info ii = p.second;
--
-- for (int pos = p.first; pos >= 0; --pos)
-+ for (int pos = start; pos >= 0; --pos)
- {
- insn_info & pp = infos[pos];
- rtx_insn * insn = pp.get_insn ();
-@@ -1352,7 +1357,7 @@ update_insn_infos (void)
- continue;
-
- /* no new information -> break. */
-- if (pp.in_proepi () == IN_CODE && pp.is_visited () && pp.contains (ii))
-+ if (pos != start && pp.is_visited () && !JUMP_P(insn) && pp.contains (ii))
- break;
-
- ii.clear_hard_def ();
-@@ -1366,8 +1371,20 @@ update_insn_infos (void)
- {
- i2i_iterator j = insn2info.find (i->second);
- if (j != insn2info.end ())
-- todo.push_back (std::make_pair (j->second->get_index (), ii));
-+ {
-+ unsigned index = j->second->get_index ();
-+ insn_info & jj = infos[index];
-+ if (!jj.is_visited () || !jj.contains (ii))
-+ {
-+ jj.updateWith (ii);
-+ todo.insert (index);
-+ }
-+ }
- }
++/* Various -m flags require special flags to the assembler. */
+
-+ if (pos == start)
-+ pp.mark_visited ();
-+// pp.update (ii);
- continue;
- }
-
-@@ -1382,7 +1399,7 @@ update_insn_infos (void)
- }
- else if (JUMP_P(insn))
- {
-- if ((unsigned) pos != p.first)
-+ if (pos != start)
- {
- su_iterator k = returns.find (pos);
- if (k != returns.end ())
-@@ -2607,7 +2624,10 @@ track_sp ()
- {
- insn_info & ii = infos[index];
- if (ii.in_proepi () != IN_CODE)
-- continue;
-+ {
-+ ii.set_sp_offset (sp_offset);
-+ continue;
-+ }
-
- // already visited? sp_offset must match
- if (ii.is_visited ())
-@@ -2847,7 +2867,7 @@ opt_shrink_stack_frame (void)
- for (unsigned i = 0; i < infos.size (); ++i)
- {
- insn_info & jj = infos[i];
-- if (jj.in_proepi () == IN_CODE)
-+ if (jj.in_proepi () != IN_CODE)
- continue;
-
- ii.or_use (jj);
-@@ -3104,7 +3124,7 @@ opt_shrink_stack_frame (void)
- log ("(f) dropping unused frame pointer\n");
- for (std::vector<int>::reverse_iterator i = a5pos.rbegin (); i != a5pos.rend (); ++i)
- {
-- unsigned index = *i;
-+ int index = *i;
- SET_INSN_DELETED(infos[index].get_insn ());
-
- // move to last insn in epilogue
-@@ -3112,7 +3132,7 @@ opt_shrink_stack_frame (void)
- --index;
-
- insn_info & ii = infos[index];
-- if (ii.get_sp_offset () != 0)
-+ if (ii.in_proepi () >= IN_EPILOGUE && ii.get_sp_offset () != 0)
- {
- log ("(f) adjusting exit sp\n");
- rtx pattern = gen_rtx_SET(a7,
-
-From aea30fb817d7af78317be6f363975ef30a56129b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 27 May 2017 00:33:52 +0200
-Subject: [PATCH 141/303] @R disabled soft float in gcc
-
----
- .project | 7 +++++++
- .settings/language.settings.xml | 2 +-
- libgcc/config.host | 3 ++-
- 3 files changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/.project b/.project
-index 22b8c5a11f48..500c9ee08dca 100644
---- .project
-+++ .project
-@@ -24,4 +24,11 @@
- <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
- <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
- </natures>
-+ <linkedResources>
-+ <link>
-+ <name>build-gcc</name>
-+ <type>2</type>
-+ <location>D:/develop/workspaces/c1/amigaos-cross-toolchain/.build-m68k/build/gcc-6</location>
-+ </link>
-+ </linkedResources>
- </projectDescription>
-diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
-index c6ac9211311a..caef162d88d1 100755
---- .settings/language.settings.xml
-+++ .settings/language.settings.xml
-@@ -16,7 +16,7 @@
- <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
- <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
- <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
-- <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="860895942062206931" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
-+ <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-910044784883564564" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
- <language-scope id="org.eclipse.cdt.core.gcc"/>
- <language-scope id="org.eclipse.cdt.core.g++"/>
- </provider>
-diff --git a/libgcc/config.host b/libgcc/config.host
-index 2eb982df6274..f456ff689ad9 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -817,7 +817,8 @@ m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
- m68k-*-amiga*)
-- tmake_file="$tmake_file m68k/t-floatlib"
-+ tmake_file="$tmake_file
-+# m68k/t-floatlib"
- ;;
- m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
-
-From 22166a8c54eedddc7f3bb718c3be733dae48d367 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sat, 27 May 2017 13:35:18 +0100
-Subject: [PATCH 142/303] @V bump datestamp
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 4d8890e894e9..3042ace073af 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170526
-+20170527-133518
-
-From bdc1872397c7c616974499050001710681d3346e Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sat, 27 May 2017 13:50:12 +0100
-Subject: [PATCH 143/303] @V bump datestamp
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 3042ace073af..cb171356c5e5 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170527-133518
-+20170527-135012
-
-From 497b371bb123e18aa03089ff176b991be46a4324 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sat, 27 May 2017 15:14:21 +0100
-Subject: [PATCH 144/303] @V bump datestamp
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index cb171356c5e5..3ebdd3995a41 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170527-135012
-+20170527-151421
-
-From 40c89d195204d51e61d08bdd7f0d10b5f1b64db7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 27 May 2017 23:28:12 +0200
-Subject: [PATCH 145/303] @R fixes for TARGET_AMIGAOS_VASM
-
----
- gcc/config/m68k/m68k.c | 13 +++++++++
- gcc/config/m68k/m68kamigaos.h | 61 ++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 73 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 3b51b2541bc9..d123cc065c18 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -4593,20 +4593,33 @@ print_operand (FILE *file, rtx op, int letter)
- {
- long l;
- REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
++#undef ASM_SPEC
+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx", l & 0xFFFFFFFF);
-+#else
-+ asm_fprintf (file, "%I$%lx", l & 0xFFFFFFFF);
-+#endif
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
- {
- long l[3];
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
- l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
++#define ASM_SPEC \
++ "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc} %{!msmall-code:-S}"
+#else
-+ asm_fprintf (file, "%I$%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
-+ l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
++#define ASM_SPEC \
++ "-gas -esc -ldots -Fhunk -quiet %(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
+#endif
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
- {
- long l[2];
- REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx%08lx", l[0] & 0xFFFFFFFF, l[1] & 0xFFFFFFFF);
++
++#undef ASM_CPU_SPEC
++#define ASM_CPU_SPEC \
++ "%{mcpu=*:-m%*} " \
++ "%{m68000|mc68000:-m68010} " \
++ "%{m6802*|mc68020:-m68020} " \
++ "%{m68030} " \
++ "%{m68040} " \
++ "%{m68060}"
++
++#ifndef TARGET_AMIGAOS_VASM
++#define ASM_CPU_DEFAULT_SPEC \
++ "%{!m680*:%{!mc680*:%{!mcpu=*:-m68000}}}"
+#else
-+ asm_fprintf (file, "%I$%lx%08lx", l[0] & 0xFFFFFFFF, l[1] & 0xFFFFFFFF);
++#define ASM_CPU_DEFAULT_SPEC \
++ "%{!m680*:%{!mc680*:-m68000}}"
+#endif
- }
- else
- {
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index a81007bb15d5..aabd0ab5e521 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -31,6 +31,17 @@ along with GCC; see the file COPYING3. If not see
- #define SWBEG_ASM_OP "\t.swbeg\t"
- #endif
-
-+#ifdef TARGET_AMIGAOS_VASM
-+#undef ASM_STABS_OP
-+#define ASM_STABS_OP "|\t.stabs\t"
+
-+#undef ASM_STABD_OP
-+#define ASM_STABD_OP "|\t.stabd\t"
++/* 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. */
+
-+#undef ASM_STABN_OP
-+#define ASM_STABN_OP "|\t.stabn\t"
-+#endif
++#define STARTFILE_IXEMUL_SPEC \
++ "%{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}}}}}}"
++#define STARTFILE_LIBNIX_SPEC \
++ "%:sdk_root(libnix/lib/libnix/ " \
++ "%{ramiga-*:" \
++ "%{ramiga-lib:libinit.o%s}" \
++ "%{ramiga-libr:libinitr.o%s}" \
++ "%{ramiga-dev:devinit.o%s}}" \
++ "%{!ramiga-*:" \
++ "%{resident:nrcrt0.o%s}" \
++ "%{!resident:" \
++ "%{fbaserel:nbcrt0.o%s}" \
++ "%{!fbaserel:" \
++ "%{fbaserel32:nlbcrt0.o%s}" \
++ "%{!fbaserel32:ncrt0.o%s}}}}" \
++ ")"
+
- #undef PIC_REG
- #define PIC_REG 12
-
-@@ -410,11 +421,16 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- ")"
-
- #undef STARTFILE_SPEC
++#define STARTFILE_CLIB2_SPEC \
++ "%:sdk_root(clib2/lib/ " \
++ "%{resident32:nr32crt0.o%s}" \
++ "%{!resident32:" \
++ "%{fbaserel32:nb32crt0.o%s}" \
++ "%{!fbaserel32:" \
++ "%{resident:nrcrt0.o%s}" \
++ "%{!resident:" \
++ "%{fbaserel:nbcrt0.o%s}" \
++ "%{!fbaserel:ncrt0.o%s}}}}" \
++ ")"
++
++#undef STARTFILE_SPEC
+#ifdef TARGET_AMIGAOS_VASM
+#define STARTFILE_SPEC \
+ "startup%O%s"
+#else
- #define STARTFILE_SPEC \
- "%{noixemul:%(startfile_libnix)} " \
- "%{mcrt=nix*:%(startfile_libnix)} " \
- "%{mcrt=ixemul:%(startfile_ixemul)} " \
- "%{mcrt=clib2:%(startfile_clib2)}"
++#define STARTFILE_SPEC \
++ "%{noixemul:%(startfile_libnix)} " \
++ "%{mcrt=nix*:%(startfile_libnix)} " \
++ "%{mcrt=ixemul:%(startfile_ixemul)} " \
++ "%{mcrt=clib2:%(startfile_clib2)} " \
++ "%{!noixemul:%{!mcrt*:%(startfile_libnix)}}"
+#endif
-
- #define ENDFILE_IXEMUL_SPEC ""
- #define ENDFILE_LIBNIX_SPEC "-lstubs"
-@@ -456,11 +472,16 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{mstackcheck:-lstack} " \
- "%{mstackextend:-lstack}"
-
++
++#define ENDFILE_IXEMUL_SPEC ""
++#define ENDFILE_LIBNIX_SPEC "-lstubs"
++#define ENDFILE_CLIB2_SPEC ""
++
++#undef ENDFILE_SPEC
++#define ENDFILE_SPEC \
++ "%{noixemul:%(endfile_libnix)} " \
++ "%{mcrt=nix*:%(endfile_libnix)} " \
++ "%{mcrt=ixemul:%(endfile_ixemul)} " \
++ "%{mcrt=clib2:%(endfile_clib2)} " \
++ "%{!noixemul:%{!mcrt*:%(endfile_libnix)}}"
++
++
++/* 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_IXEMUL_SPEC \
++ "%{!p:%{!pg:-lc -lamiga -lc}} " \
++ "%{p:-lc_p} %{pg:-lc_p}"
++#define LIB_LIBNIX_SPEC \
++ "-lnixmain -lnix " \
++ "%{mcrt=*:-l%*} " \
++ "%{!mcrt=*:-lnix20} " \
++ "-lamiga " \
++ "%{mstackcheck:-lstack} " \
++ "%{mstackextend:-lstack}"
++#define LIB_CLIB2_SPEC \
++ "-lc -lamiga -ldebug " \
++ "%{mstackcheck:-lstack} " \
++ "%{mstackextend:-lstack}"
++
+#ifdef TARGET_AMIGAOS_VASM
+#define LIB_SPEC \
+ "-lvc -lamiga "
+#else
- #define LIB_SPEC \
- "%{noixemul:%(lib_libnix)} " \
- "%{mcrt=nix*:%(lib_libnix)} " \
- "%{mcrt=ixemul:%(lib_ixemul)} " \
- "%{mcrt=clib2:%(lib_clib2)}"
++#define LIB_SPEC \
++ "%{noixemul:%(lib_libnix)} " \
++ "%{mcrt=nix*:%(lib_libnix)} " \
++ "%{mcrt=ixemul:%(lib_ixemul)} " \
++ "%{mcrt=clib2:%(lib_clib2)} " \
++ "%{!noixemul:%{!mcrt*:%(lib_libnix)}}"
+#endif
-
- #define LIBGCC_IXEMUL_SPEC ""
- #define LIBGCC_LIBNIX_SPEC "-lnix -fl libnix " \
-@@ -487,7 +508,26 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- Also, pass appropriate linker flavours depending on user-supplied
- commandline options. */
-
++
++#define LIBGCC_IXEMUL_SPEC ""
++#define LIBGCC_LIBNIX_SPEC "-lnix -fl libnix " \
++ "%{mcrt=*:-l%*} " \
++ "%{!mcrt=*:-lnix20} -lstubs"
++#define LIBGCC_CLIB2_SPEC "-lc"
++#define LIBGCC_SPEC "-lgcc " \
++ "%{noixemul:%(libgcc_libnix)} " \
++ "%{mcrt=nix*:%(libgcc_libnix)} " \
++ "%{mcrt=ixemul:%(libgcc_ixemul)} " \
++ "%{mcrt=clib2:%(libgcc_clib2)} " \
++ "%{!noixemul:%{!mcrt*:%(libgcc_libnix)}}"
++
++
++/* 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_IXEMUL_SPEC ""
++#define LINK_LIBNIX_SPEC "-L%:sdk_root(libnix/lib) -fl libnix"
++#define LINK_CLIB2_SPEC "-L%:sdk_root(clib2/lib)"
++
++/* 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. */
++
+#ifdef TARGET_AMIGAOS_VASM
- #define LINK_SPEC \
++#define LINK_SPEC \
+ "%{noixemul:%(link_libnix)} " \
+ "%{mcrt=nix*:%(link_libnix)} " \
+ "%{mcrt=ixemul:%(link_ixemul)} " \
+ "%{mcrt=clib2:%(link_clib2)} " \
++ "%{!noixemul:%{!mcrt*:%(link_libnix)}} " \
+ "%{fbaserel:%{!resident:-m amiga_bss -fl libb %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}}} " \
+ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}} " \
+ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32 %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}}} " \
@@ -29251,21 +8899,48 @@ index a81007bb15d5..aabd0ab5e521 100644
+ "%{m68020-60:-fl libm020} " \
+ "%{m68881:-fl libm881}"
+#else
- "%{noixemul:%(link_libnix)} " \
- "%{mcrt=nix*:%(link_libnix)} " \
- "%{mcrt=ixemul:%(link_ixemul)} " \
-@@ -506,6 +546,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{m68020-40:-fl libm020} " \
- "%{m68020-60:-fl libm020} " \
- "%{m68881:-fl libm881}"
++#define LINK_SPEC \
++ "%{noixemul:%(link_libnix)} " \
++ "%{mcrt=nix*:%(link_libnix)} " \
++ "%{mcrt=ixemul:%(link_ixemul)} " \
++ "%{mcrt=clib2:%(link_clib2)} " \
++ "%{!noixemul:%{!mcrt*:%(link_libnix)}} " \
++ "%{fbaserel:%{!resident:-m amiga_bss -fl libb %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}}} " \
++ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}} " \
++ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32 %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}}} " \
++ "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32 %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}} " \
++ "%{g:-amiga-debug-hunk} " \
++ "%{mcpu=68020:-fl libm020} " \
++ "%{mcpu=68030:-fl libm020} " \
++ "%{mcpu=68040:-fl libm020} " \
++ "%{mcpu=68060:-fl libm020} " \
++ "%{m68020:-fl libm020} " \
++ "%{mc68020:-fl libm020} " \
++ "%{m68030:-fl libm020} " \
++ "%{m68040:-fl libm020} " \
++ "%{m68060:-fl libm020} " \
++ "%{m68020-40:-fl libm020} " \
++ "%{m68020-60:-fl libm020} " \
++ "%{m68881:-fl libm881}"
+#endif
-
- /* Translate '-resident' to '-fbaserel' (they differ in linking stage only).
- Don't put function addresses in registers for PC-relative code. */
-@@ -524,6 +565,23 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- at the end of command line. Otherwise linker chooses generic functions
- from libgcc.a instead AmigaOS-specific counterparts from libnix.a. */
-
++
++/* 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}"
++
++#define LINK_CPU_SPEC \
++ "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \
++ "%{m68881:-fl libm881}"
++
++/* [cahirwpz] A modified copy of LINK_COMMAND_SPEC from gcc/gcc.c file.
++ Don't prepend libgcc.a to link libraries and make sure the options is
++ at the end of command line. Otherwise linker chooses generic functions
++ from libgcc.a instead AmigaOS-specific counterparts from libnix.a. */
++
+#ifdef TARGET_AMIGAOS_VASM
+#define LINK_COMMAND_SPEC \
+ "%{!fsyntax-only:" \
@@ -29283,4228 +8958,990 @@ index a81007bb15d5..aabd0ab5e521 100644
+ "%{!nostdlib:%{!nodefaultlibs:%G}} " \
+ "%{T*} }}}}}} "
+#else
- #define LINK_COMMAND_SPEC \
- "%{!fsyntax-only:" \
- "%{!c:" \
-@@ -538,7 +596,8 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{!nostdlib:%{!nodefaultlibs:%L}} " \
- "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \
- "%{!nostdlib:%{!nodefaultlibs:%G}} " \
-- "%{T*} }}}}}} " \
++#define LINK_COMMAND_SPEC \
++ "%{!fsyntax-only:" \
++ "%{!c:" \
++ "%{!M:" \
++ "%{!MM:" \
++ "%{!E:" \
++ "%{!S:" \
++ "%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} " \
++ "%{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} " \
++ "%{!A:%{!nostdlib:%{!nostartfiles:%S}}} " \
++ "%{static:} %{L*} %D %o " \
++ "%{!nostdlib:%{!nodefaultlibs:%L}} " \
++ "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \
++ "%{!nostdlib:%{!nodefaultlibs:%G}} " \
+ "%{T*} }}}}}} "
+#endif
-
- extern const char * amiga_m68k_prefix_func(int, const char **);
-
-
-From f86473acc971c74d399d0b0f7de418ab45a9cd46 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 28 May 2017 07:12:48 +0200
-Subject: [PATCH 146/303] @B fix defines
-
----
- gcc/config/m68k/m68kamigaos.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index aabd0ab5e521..a286fff9c688 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -528,6 +528,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{m68020-60:-fl libm020} " \
- "%{m68881:-fl libm881}"
- #else
-+#define LINK_SPEC \
- "%{noixemul:%(link_libnix)} " \
- "%{mcrt=nix*:%(link_libnix)} " \
- "%{mcrt=ixemul:%(link_ixemul)} " \
-
-From 205a71781ce9bd12d9360462dfcb7e87bacc382b Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 28 May 2017 06:24:32 +0100
-Subject: [PATCH 147/303] @V bump datestamp
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 3ebdd3995a41..12703d9cab62 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170527-151421
-+20170528-062432
-
-From 208ca25348e2fe8597be046ba1e841e5cddb5448 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 28 May 2017 20:39:12 +0200
-Subject: [PATCH 148/303] @I use set instead of vector to track the stack
- pointer
-
----
- gcc/bbb-opts.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 6b1a6bb5f3c0..db1d1b6b369e 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2610,13 +2610,13 @@ track_sp ()
- }
-
- // add entry point
-- std::vector<unsigned> todo;
-- todo.push_back (0);
-+ std::set<unsigned> todo;
-+ todo.insert (0);
-
-- while (todo.size () > 0)
-+ while (todo.begin () != todo.end ())
- {
-- unsigned startpos = todo[todo.size () - 1];
-- todo.pop_back ();
-+ unsigned startpos = *todo.begin ();
-+ todo.erase (todo.begin ());
-
- int sp_offset = infos[startpos].get_sp_offset ();
-
-@@ -2651,7 +2651,7 @@ track_sp ()
- return E_SP_MISMATCH;
-
- ll.set_sp_offset (sp_offset);
-- todo.push_back (i->second);
-+ todo.insert (i->second);
- }
- continue;
- }
-
-From 8f616d112701133d7bafb8db6dceb6895eead852 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 29 May 2017 11:31:30 +0200
-Subject: [PATCH 149/303] @I improved reg usage tracking and reg renaming
-
----
- gcc/bbb-opts.c | 43 ++++++++++++++++++++++++++++++-------------
- 1 file changed, 30 insertions(+), 13 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index db1d1b6b369e..0b71eef7d5c0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -677,15 +677,19 @@ class insn_info
- if (def & hard)
- return 0;
-
-- if (!def || (def & ~(1 << FIRST_PSEUDO_REGISTER)) > 0x1000)
-+ if (!def)
- return 0;
-
-- unsigned mask = def - 1;
-+ unsigned def_no_cc = def & ~(1 << FIRST_PSEUDO_REGISTER);
-+ if (def_no_cc > 0x4000)
-+ return 0;
-+
-+ unsigned mask = def_no_cc - 1;
- /* more than one register -> don't touch. */
- if ((mask & ~def) != mask)
- return 0;
-
-- if (def > 0xff)
-+ if (def_no_cc > 0xff)
- mask &= 0xff00;
-
- return mask & ~use;
-@@ -1384,7 +1388,17 @@ update_insn_infos (void)
-
- if (pos == start)
- pp.mark_visited ();
--// pp.update (ii);
+
-+ /* check previous insn for jump */
-+ if (pos > 0 && infos[pos - 1].is_jump ())
-+ {
-+ rtx_insn * prev = infos[pos - 1].get_insn ();
-+ rtx set = single_set (prev);
-+ /* unconditional? -> break! */
-+ if (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) != IF_THEN_ELSE)
-+ break;
-+ }
++extern const char * amiga_m68k_prefix_func(int, const char **);
+
- continue;
- }
-
-@@ -1492,7 +1506,9 @@ update_insns ()
- {
- returns.insert (infos.size () - 1);
- inproepilogue = IN_CODE;
-- if (ANY_RETURN_P(PATTERN (insn)))
-+ rtx set = single_set (insn);
-+ if (ANY_RETURN_P(PATTERN (insn))
-+ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) != IF_THEN_ELSE))
- continue;
- }
-
-@@ -1556,6 +1572,7 @@ update_insns ()
- {
- ii.mark_label ();
- jump_table = 0;
-+ ii.set_proepi(inproepilogue = IN_CODE);
- }
- else if (CALL_P(insn))
- {
-@@ -1677,17 +1694,17 @@ opt_reg_rename (void)
- continue;
-
- /* first = pos to start, second indicates to treat def as use. */
-- std::vector<unsigned> todo;
-+ std::set<unsigned> todo;
- std::set<unsigned> found;
- if (index + 1 < infos.size ())
-- todo.push_back (index + 1);
-+ todo.insert (index + 1);
-
- found.insert (index);
- /* a register was defined, follow all branches. */
-- while (mask && todo.size ())
-+ while (mask && todo.begin () != todo.end ())
- {
-- unsigned runpos = todo[todo.size () - 1];
-- todo.pop_back ();
-+ unsigned runpos = *todo.begin ();
-+ todo.erase (todo.begin ());
-
- for (unsigned pos = runpos; mask && pos < infos.size (); ++pos)
- {
-@@ -1716,7 +1733,7 @@ opt_reg_rename (void)
- continue;
-
- start = find_start (found, start, rename_regno);
-- todo.push_back (start);
-+ todo.insert (start);
- }
- continue;
- }
-@@ -1774,9 +1791,9 @@ opt_reg_rename (void)
- if (bb.is_use (rename_regno))
- {
- unsigned start = find_start (found, label_index, rename_regno);
-- todo.push_back (start);
-+ todo.insert (start);
- }
-- todo.push_back (label_index + 1);
-+ todo.insert (label_index + 1);
- }
- rtx jmppattern = PATTERN (insn);
- if (GET_CODE(jmppattern) == PARALLEL)
-
-From 19cecc88e679fc1926df66fc4df5feaaaa4fce63 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 29 May 2017 20:25:44 +0200
-Subject: [PATCH 150/303] @B #25 cpu defaults now to m68000 (was m68040)
-
----
- gcc/config/m68k/m68kamigaos.h | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index a286fff9c688..8a25f8cbfdfb 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -367,7 +367,8 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- #endif
-
- #undef ASM_CPU_SPEC
--#define ASM_CPU_SPEC \
-+#define ASM_CPU_SPEC \
-+ "%{mcpu=*:-m%*} " \
- "%{m68000|mc68000:-m68010} " \
- "%{m6802*|mc68020:-m68020} " \
- "%{m68030} " \
-@@ -376,7 +377,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
-
- #ifndef TARGET_AMIGAOS_VASM
- #define ASM_CPU_DEFAULT_SPEC \
-- "%{!m680*:%{!mc680*:-m68040}}"
-+ "%{!m680*:%{!mc680*:%{!mcpu=*:-m68000}}}"
- #else
- #define ASM_CPU_DEFAULT_SPEC \
- "%{!m680*:%{!mc680*:-m68000}}"
-
-From f6cdedb91a27adc4aa437490c846d0863550b011 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 29 May 2017 20:27:07 +0200
-Subject: [PATCH 151/303] @B fix handling parallel insns with set + clobber
-
----
- gcc/bbb-opts.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 0b71eef7d5c0..a76b70385d9c 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -805,7 +805,7 @@ insn_info::scan_rtx (rtx x)
- void
- insn_info::fledder (rtx set)
- {
-- if (GET_CODE(set) == PARALLEL)
-+ if (!set || GET_CODE(set) == PARALLEL)
- return;
-
- rtx dst = SET_DEST(set);
-@@ -1142,13 +1142,13 @@ insn_info::set_insn (rtx_insn * newinsn)
-
- reset_flags ();
-
-- fledder (PATTERN (insn));
-+ fledder (single_set (insn));
- }
-
- void
- insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- {
-- rtx set = PATTERN (get_insn ());
-+ rtx set = single_set (get_insn ());
- rtx src = SET_SRC(set);
- rtx dst = SET_DEST(set);
-
-@@ -1572,7 +1572,7 @@ update_insns ()
- {
- ii.mark_label ();
- jump_table = 0;
-- ii.set_proepi(inproepilogue = IN_CODE);
-+ ii.set_proepi (inproepilogue = IN_CODE);
- }
- else if (CALL_P(insn))
- {
-@@ -3100,7 +3100,7 @@ opt_shrink_stack_frame (void)
- if (ii.in_proepi () != IN_CODE)
- continue;
-
-- rtx pattern = PATTERN (ii.get_insn ());
-+ rtx pattern = single_set (ii.get_insn ());
- if (ii.is_compare ())
- pattern = XEXP(pattern, 1);
-
-
-From 5ab0b26c5f50357a306188c7348c818136106b19 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Mon, 29 May 2017 21:58:32 +0100
-Subject: [PATCH 152/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 4d8890e894e9..b5d1e40685b6 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170526
-+20170529-215512
-
-From fb1df368db776fcc6091421a2b538b346ffccad0 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 30 May 2017 19:03:36 +0200
-Subject: [PATCH 153/303] @B jumps inside epilogue which result from chained
- calls are still CALL insns...
-
----
- gcc/bbb-opts.c | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index a76b70385d9c..a187666945f0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1408,10 +1408,7 @@ update_insn_infos (void)
- insn_info use (insn);
- use.scan ();
-
-- if (CALL_P(insn))
-- {
-- }
-- else if (JUMP_P(insn))
-+ if (CALL_P(insn) || JUMP_P(insn))
- {
- if (pos != start)
- {
-@@ -1577,6 +1574,11 @@ update_insns ()
- else if (CALL_P(insn))
- {
- ii.mark_call ();
-+ if (inproepilogue)
-+ {
-+ returns.insert (infos.size () - 1);
-+ inproepilogue = IN_CODE;
-+ }
- }
- else
- {
-
-From c11163ef6d4388e710fde92c1cc609ac06b0a5fc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 30 May 2017 23:12:51 +0200
-Subject: [PATCH 154/303] @B fix single reg pop if stack frame gets removed
-
----
- gcc/bbb-opts.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index a187666945f0..a2c305c1f65c 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1132,6 +1132,15 @@ replace_reg (rtx x, unsigned regno, rtx newreg, int offset)
- void
- insn_info::a5_to_a7 (rtx a7)
- {
-+ if (proepi == IN_EPILOGUE && src_mem_reg && get_src_mem_regno () == FRAME_POINTER_REGNUM)
-+ {
-+ rtx set = single_set (insn);
-+ if (set)
-+ {
-+ SET_SRC(set) = gen_rtx_MEM(mode, gen_rtx_POST_INC(SImode, a7));
-+ return;
-+ }
-+ }
- replace_reg (PATTERN (insn), FRAME_POINTER_REGNUM, a7, -4);
- }
-
-
-From 1ebf051b5bd078fc19f105904090ffc1743752fc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 1 Jun 2017 16:05:59 +0200
-Subject: [PATCH 155/303] @B improved scan to treat endless loops (.L1: jra L1)
- and similar constructs
-
----
- gcc/bbb-opts.c | 60 +++++++++++++++++++++++++++++++++++-----------------------
- 1 file changed, 36 insertions(+), 24 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index a2c305c1f65c..26ca56bbb84d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -483,12 +483,18 @@ class insn_info
- }
-
- inline void
-- mark_use (int regno)
-+ mark_myuse (int regno)
- {
- myuse |= 1 << regno;
- use |= 1 << regno;
- }
-
-+ inline void
-+ mark_use (int regno)
-+ {
-+ use |= 1 << regno;
-+ }
++#define EXTRA_SPEC_FUNCTIONS \
++ { "sdk_root", amiga_m68k_prefix_func },
+
- inline void
- mark_def (int regno)
- {
-@@ -722,11 +728,11 @@ insn_info::scan ()
- if (sz <= 64)
- {
- mark_hard (0);
-- mark_use (0);
-+ mark_myuse (0);
- if (sz > 32)
- {
- mark_hard (1);
-- mark_use (1);
-+ mark_myuse (1);
- }
- }
- }
-@@ -739,7 +745,7 @@ insn_info::scan ()
-
- if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
- for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
-- mark_use (r);
-+ mark_myuse (r);
- }
- /* mark scratch registers. */
- mark_def (0);
-@@ -759,13 +765,13 @@ insn_info::scan_rtx (rtx x)
- if (REG_P(x))
- {
- for (int n = REG_NREGS(x), r = REGNO(x); n > 0; --n, ++r)
-- mark_use (r);
-+ mark_myuse (r);
- return;
- }
-
- if (x == cc0_rtx)
- {
-- mark_use (FIRST_PSEUDO_REGISTER);
-+ mark_myuse (FIRST_PSEUDO_REGISTER);
- return;
- }
-
-@@ -1019,7 +1025,7 @@ typedef std::multimap<unsigned, unsigned>::iterator j2l_iterator;
- static std::map<rtx_insn *, insn_info *> insn2info;
- typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
-
--static std::set<unsigned> returns;
-+static std::set<unsigned> scan_starts;
- typedef std::set<unsigned>::iterator su_iterator;
-
- static insn_info * info0;
-@@ -1137,7 +1143,7 @@ insn_info::a5_to_a7 (rtx a7)
- rtx set = single_set (insn);
- if (set)
- {
-- SET_SRC(set) = gen_rtx_MEM(mode, gen_rtx_POST_INC(SImode, a7));
-+ SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC(SImode, a7));
- return;
- }
- }
-@@ -1221,7 +1227,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- SET_INSN_DELETED(insn);
- insn = emit_insn_after (pattern, insn);
-
-- mark_use (regno);
-+ mark_myuse (regno);
-
- insn2info.insert (std::make_pair (insn, this));
- }
-@@ -1235,7 +1241,7 @@ clear (void)
- jump2label.clear ();
- insn2info.clear ();
- infos.clear ();
-- returns.clear ();
-+ scan_starts.clear ();
- }
-
- /*
-@@ -1348,9 +1354,7 @@ static void
- update_insn_infos (void)
- {
- /* add all return (jump outs) and start analysis there. */
-- std::set<unsigned> todo;
-- for (su_iterator i = returns.begin (); i != returns.end (); ++i)
-- todo.insert (*i);
-+ std::set<unsigned> & todo = scan_starts;
-
- if (todo.begin () == todo.end ())
- todo.insert (infos.size () - 1);
-@@ -1417,12 +1421,13 @@ update_insn_infos (void)
- insn_info use (insn);
- use.scan ();
-
-+ /* do not mark a node as visited, if it's in epilogue and not yet visited. */
- if (CALL_P(insn) || JUMP_P(insn))
- {
-- if (pos != start)
-+ if (pos != start && ii.in_proepi ())
- {
-- su_iterator k = returns.find (pos);
-- if (k != returns.end ())
-+ su_iterator k = scan_starts.find (pos);
-+ if (k != scan_starts.end ())
- {
- pp.clear_visited ();
- break;
-@@ -1510,7 +1515,7 @@ update_insns ()
- {
- if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
- {
-- returns.insert (infos.size () - 1);
-+ scan_starts.insert (infos.size () - 1);
- inproepilogue = IN_CODE;
- rtx set = single_set (insn);
- if (ANY_RETURN_P(PATTERN (insn))
-@@ -1579,13 +1584,15 @@ update_insns ()
- ii.mark_label ();
- jump_table = 0;
- ii.set_proepi (inproepilogue = IN_CODE);
-+ if (infos.size () > 1)
-+ scan_starts.insert (infos.size () - 1);
- }
- else if (CALL_P(insn))
- {
- ii.mark_call ();
- if (inproepilogue)
- {
-- returns.insert (infos.size () - 1);
-+ scan_starts.insert (infos.size () - 1);
- inproepilogue = IN_CODE;
- }
- }
-@@ -1614,7 +1621,7 @@ update_insns ()
- inproepilogue = IN_EPILOGUE;
- }
- }
--
-+ scan_starts.insert (infos.size () - 1);
- update_insn2index ();
- update_insn_infos ();
-
-@@ -1666,14 +1673,17 @@ find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
- break;
-
- /* do not run over RETURNS */
-- rtx_insn * before = infos[startm1].get_insn ();
-- if (JUMP_P(before) && ANY_RETURN_P(PATTERN (before)))
-+ insn_info & jj = infos[start];
-+ insn_info & bb = infos[startm1];
-+ if (jj.in_proepi () == IN_CODE && bb.in_proepi () >= IN_EPILOGUE)
- break;
-+// rtx_insn * before = infos[startm1].get_insn ();
-+// if (JUMP_P(before) && ANY_RETURN_P(PATTERN (before)))
-+// break;
-
- start = startm1;
-
- /* found the definition without use. */
-- insn_info & jj = infos[start];
- if (jj.is_def (rename_regno) && !jj.is_use (rename_regno))
- break;
-
-@@ -3351,6 +3361,8 @@ opt_absolute (void)
- else
- log ("(b) modifying %d absolute addresses using %s\n", found.size (), reg_names[regno]);
-
-+ unsigned current_use = ii.get_use ();
++/* 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.
+
- for (std::vector<unsigned>::iterator k = found.begin (); k != found.end (); ++k)
- {
- insn_info & kk = infos[*k];
-@@ -3373,7 +3385,7 @@ opt_absolute (void)
- lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
- rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
- insn_info nn (insn);
-- nn.set_use (ii.get_use ());
-+ nn.set_use (current_use);
- nn.scan ();
- nn.fledder (lea);
- nn.mark_def (regno);
-@@ -3496,7 +3508,7 @@ namespace
- done = 0, update_insns ();
-
- if (do_absolute && opt_absolute ())
-- done = 0;
-+ done = 0, update_insns ();
-
- if (do_bb_reg_rename)
- {
-
-From 21a94abb83e5a01f912dbc66951cc32797d05ed3 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 2 Jun 2017 20:11:26 +0200
-Subject: [PATCH 156/303] @B fix opt_reg_rename: backward search for defs was
- off by one @N startet to add register tracking
-
----
- gcc/bbb-opts.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 193 insertions(+), 43 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 26ca56bbb84d..9014295f8b43 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -167,16 +167,31 @@ class insn_info
- int dst_autoinc;
- int src_autoinc;
-
-+ // values for all variables - if used
-+ rtx * values;
++ Each subgrouping contains a string constant, that defines the
++ specification name, and a string constant that used by the GCC driver
++ program.
+
- public:
- insn_info (rtx_insn * i = 0, enum proepis p = IN_CODE) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
- (rtx_code) 0), src_ee (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (
- 0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (0), visited (
-- false), sp_offset (0), dst_autoinc (0), src_autoinc (0)
-+ false), sp_offset (0), dst_autoinc (0), src_autoinc (0), values (0)
- {
- }
-
-+ void
-+ set_values (rtx * v);
++ 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 }, \
++ {"cpp_ixemul", CPP_IXEMUL_SPEC}, \
++ {"cpp_libnix", CPP_LIBNIX_SPEC}, \
++ {"cpp_clib2", CPP_CLIB2_SPEC}, \
++ {"lib_ixemul", LIB_IXEMUL_SPEC}, \
++ {"lib_libnix", LIB_LIBNIX_SPEC}, \
++ {"lib_clib2", LIB_CLIB2_SPEC}, \
++ {"link_ixemul", LINK_IXEMUL_SPEC}, \
++ {"link_libnix", LINK_LIBNIX_SPEC}, \
++ {"link_clib2", LINK_CLIB2_SPEC}, \
++ {"startfile_ixemul", STARTFILE_IXEMUL_SPEC}, \
++ {"startfile_libnix", STARTFILE_LIBNIX_SPEC}, \
++ {"startfile_clib2", STARTFILE_CLIB2_SPEC}, \
++ {"endfile_ixemul", ENDFILE_IXEMUL_SPEC}, \
++ {"endfile_libnix", ENDFILE_LIBNIX_SPEC}, \
++ {"endfile_clib2", ENDFILE_CLIB2_SPEC}, \
++ {"libgcc_ixemul", LIBGCC_IXEMUL_SPEC}, \
++ {"libgcc_libnix", LIBGCC_LIBNIX_SPEC}, \
++ {"libgcc_clib2", LIBGCC_CLIB2_SPEC}
+
-+ bool
-+ merge_values (rtx * v);
++/* begin-GG-local: dynamic libraries */
+
-+ bool
-+ equal_values (rtx * v) const;
++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 *);
+
-+ rtx
-+ get_value_for (unsigned regno) const;
++/* This macro is used to check if all collect2 facilities should be used.
++ We need a few special ones, like stripping after linking. */
+
- inline ptrdiff_t
- operator < (insn_info const & o) const
- {
-@@ -421,7 +436,7 @@ class insn_info
- return stack;
- }
-
-- inline int
-+ inline enum proepis
- in_proepi () const
- {
- return proepi;
-@@ -716,6 +731,56 @@ class insn_info
- a5_to_a7 (rtx a7);
- };
-
-+void
-+insn_info::set_values (rtx * v)
-+{
-+ if (!values)
-+ values = new rtx[16];
-+ memcpy (values, v, 16 * sizeof(rtx));
-+}
++#define DO_COLLECTING (do_collecting || amigaos_do_collecting())
+
-+static const rtx INVALID = (rtx) -1;
++/* This macro is called in collect2 for every GCC argument name.
++ ARG is a part of commandline (without '\0' at the end). */
+
-+bool
-+insn_info::merge_values (rtx * v)
-+{
-+ bool r = false;
-+ if (!values)
-+ r = true, set_values (v);
-+ else
-+ for (int i = 0; i < 16; ++i)
-+ if (!values[i])
-+ r = true, values[i] = v[i];
-+ else if (values[i] != INVALID && v[i] && v[i] != INVALID && !rtx_equal_p (values[i], v[i]))
-+ r = true, values[i] = INVALID;
-+ return r;
-+}
++#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG)
+
-+bool
-+insn_info::equal_values (rtx * v) const
-+{
-+ if (!values)
-+ return false;
-+ for (int i = 0; i < 16; ++i)
-+ if (values[i] && !v[i])
-+ return false;
-+ else if (v[i] && !values[i])
-+ return false;
-+ else if (values[i] == INVALID && v[i] != INVALID)
-+ return false;
-+ else if (!rtx_equal_p (values[i], v[i]))
-+ return false;
-+ return true;
-+}
++/* 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. */
+
-+rtx
-+insn_info::get_value_for (unsigned regno) const
-+{
-+ if (!values || regno > 15)
-+ return 0;
-+ return values[regno];
-+}
++#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG)
+
- void
- insn_info::scan ()
- {
-@@ -1365,13 +1430,18 @@ update_insn_infos (void)
- todo.erase (todo.begin ());
- insn_info ii = infos[start];
-
-+ enum proepis proepi = ii.in_proepi ();
++/* This macro is called at collect2 exit, to clean everything up. */
+
- for (int pos = start; pos >= 0; --pos)
- {
- insn_info & pp = infos[pos];
- rtx_insn * insn = pp.get_insn ();
-- /* can be NULL as used in opt_shrink_stack_frame(). */
-- if (!insn)
-- continue;
++#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup
+
-+ // do not run into previous epilogue
-+ if (pp.in_proepi () >= IN_EPILOGUE && !proepi)
-+ break;
++/* 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. */
+
-+ proepi = pp.in_proepi ();
-
- /* no new information -> break. */
- if (pos != start && pp.is_visited () && !JUMP_P(insn) && pp.contains (ii))
-@@ -1677,16 +1747,12 @@ find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
- insn_info & bb = infos[startm1];
- if (jj.in_proepi () == IN_CODE && bb.in_proepi () >= IN_EPILOGUE)
- break;
--// rtx_insn * before = infos[startm1].get_insn ();
--// if (JUMP_P(before) && ANY_RETURN_P(PATTERN (before)))
--// break;
--
-- start = startm1;
-
- /* found the definition without use. */
- if (jj.is_def (rename_regno) && !jj.is_use (rename_regno))
- break;
-
-+ start = startm1;
- }
- return start;
- }
-@@ -2531,39 +2597,6 @@ opt_const_cmp_to_sub (void)
- return change_count;
- }
-
--/*
-- * Some optimizations (e.g. propagate_moves) might result into an unused assignment behind the loop.
-- * delete those insns.
-- */
--static unsigned
--opt_elim_dead_assign (void)
--{
-- unsigned change_count = 0;
-- for (int index = infos.size () - 1; index >= 0; --index)
-- {
-- rtx_insn * insn = infos[index].get_insn ();
-- if (!NONJUMP_INSN_P(insn))
-- continue;
--
-- rtx set = single_set (insn);
-- if (!set)
-- continue;
--
-- rtx src = SET_SRC(set);
-- rtx dst = SET_DEST(set);
-- if (!REG_P(dst) || !REG_P(src))
-- continue;
--
-- if (is_reg_dead (REGNO(dst), index))
-- {
-- log ("(e) %d: elim_dead_assign to %s\n", index, reg_names[REGNO(dst)]);
-- SET_INSN_DELETED(insn);
-- ++change_count;
-- }
-- }
-- return change_count;
--}
--
- /*
- * rare and only little gain - but :-)
- lea (-1,a0),a1
-@@ -3233,6 +3266,123 @@ opt_shrink_stack_frame (void)
- return changed;
- }
-
-+/* Update the insn_infos to 'know' the value for each register. */
-+static unsigned
-+track_regs ()
-+{
-+ // reset visited flags
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ ii.clear_visited ();
-+ ii.set_sp_offset (0);
-+ }
++#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
++amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
+
-+ // add entry point
-+ std::set<unsigned> todo;
-+ todo.insert (0);
++/* This macro is called just after the first linker invocation, in place of
++ "nm" and "ldd". OUTPUT_FILE is the executable's filename. */
+
-+ while (todo.begin () != todo.end ())
-+ {
-+ unsigned startpos = *todo.begin ();
-+ todo.erase (todo.begin ());
++#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
++/* end-GG-local */
+
-+ rtx * values = new rtx[16]; // track dx/ax
-+ memset (values, 0, 16 * sizeof(rtx));
++#undef MAX_OFILE_ALIGNMENT
++#define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT)
+
-+ for (unsigned index = startpos; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
++#undef FIXED_INCLUDE_DIR
++#define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../include"
+
-+ // already visited?
-+ if (ii.is_visited () && ii.equal_values (values))
-+ break;
++// this disables tree_loop_distribute_patterns
++#define C_COMMON_OVERRIDE_OPTIONS flag_no_builtin = 1
++/* Baserel support. */
+
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
++extern int amiga_is_const_pic_ref(const_rtx x);
+
-+ ii.merge_values (values);
++#undef CONSTANT_ADDRESS_P
++#define CONSTANT_ADDRESS_P(X) \
++((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
++ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
++ || GET_CODE (X) == HIGH \
++ ))
+
-+ // add all referred labels
-+ if (ii.is_jump ())
-+ {
-+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i)
-+ {
-+ todo.insert (i->second);
-+ insn_info & jj = infos[i->second];
-+ if (jj.merge_values (values))
-+ ii.clear_visited ();
-+ }
-+ continue;
-+ }
+
-+ // track register values for now
-+ int regno = ii.get_dst_regno ();
-+ if (regno < 0)
-+ {
-+ // TODO: track if dst_mem is volatile
-+ continue;
-+ }
+
-+ rtx set = single_set (ii.get_insn ());
-+ if (!set)
-+ continue;
++/* Given that symbolic_operand(X), return TRUE if no special
++ base relative relocation is necessary */
+
-+ rtx src = SET_SRC(set);
++#undef LEGITIMATE_PIC_OPERAND_P
++#define LEGITIMATE_PIC_OPERAND_P(X) ( \
++ ! symbolic_operand (X, VOIDmode) && \
++ ! amiga_is_const_pic_ref(X))
+
-+ // TODO: check for volatile sources
-+ values[regno] = src;
++// (GET_CODE(X) == CONST && (GET_CODE(XEXP(X, 0)) == SYMBOL_REF || GET_CODE(XEXP(X, 0)) == LABEL_REF) && !CONSTANT_POOL_ADDRESS_P (XEXP(X, 0))) ||
+
-+ for (int i = regno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i)
-+ values[regno] = INVALID;
-+ }
-+ }
-+ return 0;
-+}
++#undef TARGET_GCC_EXCEPT_TABLE
++#define TARGET_GCC_EXCEPT_TABLE ".text"
+
-+/*
-+ * Some optimizations (e.g. propagate_moves) might result into an unused assignment behind the loop.
-+ * delete those insns.
-+ */
-+static unsigned
-+opt_elim_dead_assign (void)
-+{
-+ track_regs ();
++#undef TARGET_GCC_EXCEPT_TABLE_S
++#define TARGET_GCC_EXCEPT_TABLE_S ".text"
+
-+ unsigned change_count = 0;
-+ for (int index = infos.size () - 1; index >= 0; --index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (!ii.get_dst_reg ())
-+ continue;
++#define EH_TABLES_CAN_BE_READ_ONLY 1
+
-+ rtx_insn * insn = ii.get_insn ();
-+ rtx set = single_set (insn);
-+ if (!set)
+
-+ if (ii.get_src_reg () && is_reg_dead (ii.get_dst_regno (), index))
-+ {
-+ log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
++/* 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 AMIGAOS_MAX_REGPARM
++#define AMIGAOS_MAX_REGPARM 4
+
-+ continue;
++/* The default number of data, address and float registers to use when
++ user specified '-mregparm' switch, not '-mregparm=<value>' option. */
++#undef AMIGAOS_DEFAULT_REGPARM
++#define AMIGAOS_DEFAULT_REGPARM 2
+
-+ rtx cached_value = ii.get_value_for (ii.get_dst_regno ());
-+ if (cached_value && cached_value != INVALID && rtx_equal_p (cached_value, SET_SRC(set)))
-+ {
-+ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
++/* 1 if N is a possible register number for function argument passing. */
++#undef FUNCTION_ARG_REGNO_P
++#define FUNCTION_ARG_REGNO_P(N) amigaos_function_arg_reg(N)
+
-+ }
-+ }
-+ return change_count;
-+}
++extern int
++amigaos_function_arg_reg(unsigned regno);
+
- /*
- * Convert a series of move into absolute address into register based moves.
- */
-
-From 98fb7816dc4ef9e568a068343dbcf331ccdca4d0 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 3 Jun 2017 17:40:50 +0200
-Subject: [PATCH 157/303] @B fix opt_shrink_stack_frame: not all sp offsets
- were patched
-
----
- gcc/bbb-opts.c | 120 +++++++++++++++++++++++++++++++++++----------------------
- 1 file changed, 74 insertions(+), 46 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 9014295f8b43..00ac220456b2 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -146,6 +146,7 @@ class insn_info
- bool src_plus;
- rtx_code src_op;
- bool src_ee;
-+ bool src_2nd;
- bool src_const;
-
- machine_mode mode;
-@@ -174,9 +175,9 @@ class insn_info
- insn_info (rtx_insn * i = 0, enum proepis p = IN_CODE) :
- insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label (false), jump (false), call (
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
-- (rtx_code) 0), src_ee (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (0), dst_symbol (
-- 0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (0), visited (
-- false), sp_offset (0), dst_autoinc (0), src_autoinc (0), values (0)
-+ (rtx_code) 0), src_ee (false), src_2nd (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (
-+ 0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (
-+ 0), visited (false), sp_offset (0), dst_autoinc (0), src_autoinc (0), values (0)
- {
- }
-
-@@ -240,6 +241,12 @@ class insn_info
- return src_mem;
- }
++//extern bool debug_recog(char const * txt, int which_alternative, int n, rtx * operands);
+diff --git a/gcc/config/m68k/m68kemb.h b/gcc/config/m68k/m68kemb.h
+index 0d8d88c74ea9..29b3e194f12d 100644
+--- gcc/config/m68k/m68kemb.h
++++ gcc/config/m68k/m68kemb.h
+@@ -32,12 +32,14 @@
+ #define NEEDS_UNTYPED_CALL 1
-+ inline bool
-+ is_src_mem_2nd () const
-+ {
-+ return src_2nd && src_mem;
-+ }
-+
- inline bool
- has_dst_memreg () const
- {
-@@ -408,6 +415,9 @@ class insn_info
- void
- fledder (rtx set);
+ /* Target OS builtins. */
++#ifndef TARGET_OS_CPP_BUILTINS
+ #define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__embedded__"); \
+ } \
+ while (0)
++#endif
-+ void
-+ fledder_src_mem (rtx src);
-+
- /* update usage. */
- void
- update (insn_info & o)
-@@ -872,6 +882,51 @@ insn_info::scan_rtx (rtx x)
- }
- }
+ /* Override the default LIB_SPEC from gcc.c. We don't currently support
+ profiling, or libg.a. */
+diff --git a/gcc/config/m68k/math-68881.h b/gcc/config/m68k/math-68881.h
+index 6d9f8b2d4a1f..20a5037cc525 100644
+--- gcc/config/m68k/math-68881.h
++++ gcc/config/m68k/math-68881.h
+@@ -37,7 +37,7 @@
+ September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif. */
-+void
-+insn_info::fledder_src_mem (rtx src)
-+{
-+ src_mem = true;
-+ rtx mem = XEXP(src, 0);
-+
-+ if (GET_CODE(mem) == POST_INC)
-+ src_autoinc = 1, mem = XEXP(mem, 0);
-+ else if (GET_CODE(mem) == PRE_DEC)
-+ src_autoinc = -1, mem = XEXP(mem, 0);
-+
-+ if (REG_P(mem))
-+ src_mem_reg = mem;
-+ else if (GET_CODE(mem) == CONST_INT)
-+ src_mem_addr = INTVAL(mem);
-+ else if (GET_CODE(mem) == SYMBOL_REF)
-+ src_symbol = mem;
-+ else if (GET_CODE(mem) == PLUS)
-+ {
-+ src_plus = true;
-+ rtx reg = XEXP(mem, 0);
-+ rtx konst = XEXP(mem, 1);
-+ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-+ {
-+ src_mem_reg = reg;
-+ src_const = true;
-+ src_mem_addr = INTVAL(konst);
-+ }
-+ }
-+ else if (GET_CODE(mem) == CONST)
-+ {
-+ mem = XEXP(mem, 0);
-+ if (GET_CODE(mem) == PLUS)
-+ {
-+ rtx sym = XEXP(mem, 0);
-+ if (GET_CODE(sym) == SYMBOL_REF)
-+ {
-+ src_plus = true;
-+ src_symbol = sym;
-+ src_mem_addr = INTVAL(XEXP(mem, 1));
-+ }
-+ }
-+ }
-+}
-+
- /* read the set and grab infos */
- void
- insn_info::fledder (rtx set)
-@@ -959,7 +1014,15 @@ insn_info::fledder (rtx set)
- if (GET_CODE(operand) == CONST_INT || GET_CODE(operand) == CONST_WIDE_INT)
- src_const = true, src_intval = INTVAL(operand);
- else if (REG_P(operand))
-- alt_src_reg = operand;
-+ {
-+ alt_src_reg = operand;
-+ }
-+ else if (MEM_P(operand))
-+ {
-+ // it' something like reg = op(reg, mem(...))
-+ src_2nd = true;
-+ fledder_src_mem (operand);
-+ }
- }
- src = XEXP(src, 0);
- }
-@@ -970,46 +1033,7 @@ insn_info::fledder (rtx set)
- }
- else if (MEM_P(src))
- {
-- src_mem = true;
-- rtx mem = XEXP(src, 0);
--
-- if (GET_CODE(mem) == POST_INC)
-- src_autoinc = 1, mem = XEXP(mem, 0);
-- else if (GET_CODE(mem) == PRE_DEC)
-- src_autoinc = -1, mem = XEXP(mem, 0);
--
-- if (REG_P(mem))
-- src_mem_reg = mem;
-- else if (GET_CODE(mem) == CONST_INT)
-- src_mem_addr = INTVAL(mem);
-- else if (GET_CODE(mem) == SYMBOL_REF)
-- src_symbol = mem;
-- else if (GET_CODE(mem) == PLUS)
-- {
-- src_plus = true;
-- rtx reg = XEXP(mem, 0);
-- rtx konst = XEXP(mem, 1);
-- if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-- {
-- src_mem_reg = reg;
-- src_const = true;
-- src_mem_addr = INTVAL(konst);
-- }
-- }
-- else if (GET_CODE(mem) == CONST)
-- {
-- mem = XEXP(mem, 0);
-- if (GET_CODE(mem) == PLUS)
-- {
-- rtx sym = XEXP(mem, 0);
-- if (GET_CODE(sym) == SYMBOL_REF)
-- {
-- src_plus = true;
-- src_symbol = sym;
-- src_mem_addr = INTVAL(XEXP(mem, 1));
-- }
-- }
-- }
-+ fledder_src_mem (src);
- }
- else if (GET_CODE(src) == CONST_INT)
- {
-@@ -3173,7 +3197,11 @@ opt_shrink_stack_frame (void)
- rtx src = XEXP(pattern, 1);
- rtx plus = XEXP(src, 0);
- if (ii.get_src_op ())
-- plus = XEXP(plus, 0);
-+ {
-+ plus = XEXP(src, 1);
-+ if (MEM_P(plus))
-+ plus = XEXP(plus, 0);
-+ }
- XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), ii.get_src_mem_addr () - adjust);
- }
+ /* Changed by Ian Lance Taylor:
+- September 1994, use extern inline instead of static inline. */
++ September 1994, use inline instead of static inline. */
-@@ -3333,7 +3361,7 @@ track_regs ()
- // TODO: check for volatile sources
- values[regno] = src;
+ #ifndef __math_68881
+ #define __math_68881
+@@ -64,7 +64,7 @@
+ })
+ #endif
-- for (int i = regno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i)
-+ for (unsigned i = regno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i)
- values[regno] = INVALID;
- }
- }
-
-From 3d0257b6111e90dab6f704f81bb6c0a5adc3191f Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sat, 3 Jun 2017 19:01:51 +0100
-Subject: [PATCH 158/303] @V bump datestamp
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index b5d1e40685b6..54bc2fee3dce 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170529-215512
-+20170603-190132
-
-From a64448fa986d1e9e89b7214926213844749cb330 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 4 Jun 2017 10:54:35 +0200
-Subject: [PATCH 159/303] @B removed bogus (and not yet used) code
-
----
- gcc/bbb-opts.c | 86 ----------------------------------------------------------
- 1 file changed, 86 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 00ac220456b2..11c3891025e9 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3294,80 +3294,6 @@ opt_shrink_stack_frame (void)
- return changed;
+-__inline extern double
++__inline double
+ sin (double x)
+ {
+ double value;
+@@ -75,7 +75,7 @@ sin (double x)
+ return value;
}
--/* Update the insn_infos to 'know' the value for each register. */
--static unsigned
--track_regs ()
--{
-- // reset visited flags
-- for (unsigned index = 0; index < infos.size (); ++index)
-- {
-- insn_info & ii = infos[index];
-- ii.clear_visited ();
-- ii.set_sp_offset (0);
-- }
--
-- // add entry point
-- std::set<unsigned> todo;
-- todo.insert (0);
--
-- while (todo.begin () != todo.end ())
-- {
-- unsigned startpos = *todo.begin ();
-- todo.erase (todo.begin ());
--
-- rtx * values = new rtx[16]; // track dx/ax
-- memset (values, 0, 16 * sizeof(rtx));
--
-- for (unsigned index = startpos; index < infos.size (); ++index)
-- {
-- insn_info & ii = infos[index];
--
-- // already visited?
-- if (ii.is_visited () && ii.equal_values (values))
-- break;
--
-- // mark current insn_info and set sp_offset
-- ii.mark_visited ();
--
-- ii.merge_values (values);
--
-- // add all referred labels
-- if (ii.is_jump ())
-- {
-- for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i)
-- {
-- todo.insert (i->second);
-- insn_info & jj = infos[i->second];
-- if (jj.merge_values (values))
-- ii.clear_visited ();
-- }
-- continue;
-- }
--
-- // track register values for now
-- int regno = ii.get_dst_regno ();
-- if (regno < 0)
-- {
-- // TODO: track if dst_mem is volatile
-- continue;
-- }
--
-- rtx set = single_set (ii.get_insn ());
-- if (!set)
-- continue;
--
-- rtx src = SET_SRC(set);
--
-- // TODO: check for volatile sources
-- values[regno] = src;
--
-- for (unsigned i = regno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i)
-- values[regno] = INVALID;
-- }
-- }
-- return 0;
--}
--
- /*
- * Some optimizations (e.g. propagate_moves) might result into an unused assignment behind the loop.
- * delete those insns.
-@@ -3375,8 +3301,6 @@ track_regs ()
- static unsigned
- opt_elim_dead_assign (void)
+-__inline extern double
++__inline double
+ cos (double x)
{
-- track_regs ();
--
- unsigned change_count = 0;
- for (int index = infos.size () - 1; index >= 0; --index)
- {
-@@ -3397,16 +3321,6 @@ opt_elim_dead_assign (void)
- }
-
- continue;
--
-- rtx cached_value = ii.get_value_for (ii.get_dst_regno ());
-- if (cached_value && cached_value != INVALID && rtx_equal_p (cached_value, SET_SRC(set)))
-- {
-- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-- SET_INSN_DELETED(insn);
-- ++change_count;
-- continue;
--
-- }
- }
- return change_count;
+ double value;
+@@ -86,7 +86,7 @@ cos (double x)
+ return value;
}
-
-From 5a66c60ad7bba806de2640310c4e3e4941245aa2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 5 Jun 2017 00:00:30 +0200
-Subject: [PATCH 160/303] @B fix reg use/def marking in ASM_SPEC, @B rewrote SP
- offset patcher, @N added variable tracking and (e)liminate redundat load
-
----
- gcc/bbb-opts.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++---------
- 1 file changed, 251 insertions(+), 45 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 11c3891025e9..e9a8df7d1c01 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -181,6 +181,9 @@ class insn_info
- {
- }
-
-+ rtx *
-+ get_values ();
-+
- void
- set_values (rtx * v);
-
-@@ -741,12 +744,23 @@ class insn_info
- a5_to_a7 (rtx a7);
- };
-+rtx *
-+insn_info::get_values ()
-+{
-+ if (values)
-+ return values;
-+
-+ values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx));
-+ memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx));
-+ return values;
-+}
-+
- void
- insn_info::set_values (rtx * v)
+-__inline extern double
++__inline double
+ tan (double x)
{
- if (!values)
-- values = new rtx[16];
-- memcpy (values, v, 16 * sizeof(rtx));
-+ values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx));
-+ memcpy (values, v, FIRST_PSEUDO_REGISTER * sizeof(rtx));
+ double value;
+@@ -97,7 +97,7 @@ tan (double x)
+ return value;
}
- static const rtx INVALID = (rtx) -1;
-@@ -758,7 +772,7 @@ insn_info::merge_values (rtx * v)
- if (!values)
- r = true, set_values (v);
- else
-- for (int i = 0; i < 16; ++i)
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- if (!values[i])
- r = true, values[i] = v[i];
- else if (values[i] != INVALID && v[i] && v[i] != INVALID && !rtx_equal_p (values[i], v[i]))
-@@ -771,7 +785,7 @@ insn_info::equal_values (rtx * v) const
+-__inline extern double
++__inline double
+ asin (double x)
{
- if (!values)
- return false;
-- for (int i = 0; i < 16; ++i)
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- if (values[i] && !v[i])
- return false;
- else if (v[i] && !values[i])
-@@ -857,6 +871,7 @@ insn_info::scan_rtx (rtx x)
- {
- unsigned u = use;
- unsigned mu = myuse;
-+ use = myuse = 0;
- scan_rtx (SET_DEST(x));
- if (REG_P(SET_DEST(x)))
- {
-@@ -867,7 +882,7 @@ insn_info::scan_rtx (rtx x)
- scan_rtx (SET_SRC(x));
- int code = GET_CODE(SET_SRC(x));
- if (code == ASM_OPERANDS)
-- use = hard |= def | use;
-+ hard |= def | use;
- return;
- }
-
-@@ -878,7 +893,15 @@ insn_info::scan_rtx (rtx x)
- scan_rtx (XEXP(x, i));
- else if (fmt[i] == 'E')
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-- scan_rtx (XVECEXP(x, i, j));
-+ {
-+ unsigned u = use;
-+ unsigned mu = myuse;
-+ unsigned d = def;
-+ scan_rtx (XVECEXP(x, i, j));
-+ use |= u;
-+ myuse |= myuse;
-+ def |= d;
-+ }
- }
+ double value;
+@@ -108,7 +108,7 @@ asin (double x)
+ return value;
}
-@@ -2775,6 +2798,33 @@ track_sp ()
- return 0;
+-__inline extern double
++__inline double
+ acos (double x)
+ {
+ double value;
+@@ -119,7 +119,7 @@ acos (double x)
+ return value;
}
-+/* recursive function to patch stack pointer offsets. */
-+void
-+patch_sp (rtx x, int adjust, int spoffset)
-+{
-+ int code = GET_CODE(x);
-+ if (code == PLUS)
-+ {
-+ rtx a = XEXP(x, 0);
-+ rtx b = XEXP(x, 1);
-+ if (REG_P(a) && REGNO(a) == STACK_POINTER_REGNUM && GET_CODE(b) == CONST_INT)
-+ {
-+ if (INTVAL(b) > -spoffset)
-+ XEXP(x, 1) = gen_rtx_CONST_INT (GET_MODE(b), INTVAL(b) - adjust);
-+ return;
-+ }
-+ }
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ patch_sp (XEXP(x, i), adjust, spoffset);
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ patch_sp (XVECEXP(x, i, j), adjust, spoffset);
-+ }
-+}
-+
- /**
- * 1. scan for all used registers.
- * 2. scan the stack from for omittable push/pop
-@@ -3179,37 +3229,8 @@ opt_shrink_stack_frame (void)
- continue;
-
- rtx pattern = single_set (ii.get_insn ());
-- if (ii.is_compare ())
-- pattern = XEXP(pattern, 1);
--
-- // lea n(sp),ax
-- if (ii.get_src_reg () && ii.get_src_regno () == STACK_POINTER_REGNUM && ii.get_src_op () == PLUS)
-- {
-- // touch only if above pushed parameters
-- if (ii.get_src_intval () > -ii.get_sp_offset ())
-- {
-- rtx src = XEXP(pattern, 1);
-- XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), ii.get_src_intval () - adjust);
-- }
-- }
-- else if (ii.is_src_mem () && ii.is_src_mem_plus () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM)
-- {
-- rtx src = XEXP(pattern, 1);
-- rtx plus = XEXP(src, 0);
-- if (ii.get_src_op ())
-- {
-- plus = XEXP(src, 1);
-- if (MEM_P(plus))
-- plus = XEXP(plus, 0);
-- }
-- XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), ii.get_src_mem_addr () - adjust);
-- }
--
-- if (ii.is_dst_mem () && ii.is_dst_mem_plus () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM)
-- {
-- rtx plus = XEXP(XEXP(pattern, 0), 0);
-- XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), ii.get_dst_intval () - adjust);
-- }
-+ if (pattern)
-+ patch_sp (pattern, adjust, ii.get_sp_offset ());
- }
- }
-
-@@ -3294,6 +3315,168 @@ opt_shrink_stack_frame (void)
- return changed;
+-__inline extern double
++__inline double
+ atan (double x)
+ {
+ double value;
+@@ -130,7 +130,7 @@ atan (double x)
+ return value;
}
-+/* Update the insn_infos to 'know' the value for each register. */
-+static unsigned
-+track_regs ()
-+{
-+ // reset visited flags
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ ii.clear_visited ();
-+ ii.set_sp_offset (0);
-+ }
-+
-+ rtx * values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx)); // track register values
-+
-+ // add entry point
-+ std::set<unsigned> todo;
-+ todo.insert (0);
-+
-+ while (todo.begin () != todo.end ())
-+ {
-+ unsigned startpos = *todo.begin ();
-+ todo.erase (todo.begin ());
-+
-+ memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx));
-+
-+ // track register aliases: know which register refers to this slot
-+ // if a register changes, invalidate each referrer
-+ std::multimap<unsigned, unsigned> r2r;
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ if (values[i] && values[i] != INVALID && REG_P(values[i]))
-+ r2r.insert (std::make_pair (REGNO(values[i]), i));
-+
-+ for (unsigned index = startpos; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ // already visited?
-+ if (ii.is_visited () && ii.equal_values (values))
-+ break;
-+
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
-+
-+ // do not optimize over labels
-+ if (ii.is_label ())
-+ {
-+ memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx));
-+ continue;
-+ }
-+
-+ ii.merge_values (values);
-+
-+ if (ii.is_compare ())
-+ continue;
-+
-+ unsigned def = ii.get_def ();
-+ if (def)
-+ {
-+ for (int i = 0; i < 16; ++i)
-+ if ((1 << i) & def)
-+ {
-+ values[i] = 0;
-+ // invalidate all referring registers
-+ for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (i), k = j;
-+ j != r2r.end () && j->first == k->first;)
-+ {
-+ values[j->second] = INVALID;
-+ r2r.erase (j++);
-+ }
-+ }
-+ }
-+
-+ if (ii.is_call ())
-+ continue;
-+
-+ // add all referred labels
-+ if (ii.is_jump ())
-+ {
-+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i)
-+ {
-+ todo.insert (i->second);
-+ insn_info & jj = infos[i->second];
-+ if (jj.merge_values (values))
-+ ii.clear_visited ();
-+ }
-+ continue;
-+ }
-+
-+ rtx set = single_set (ii.get_insn ());
-+ if (!set)
-+ continue;
-+
-+ rtx src, dest;
-+ if (ii.get_src_autoinc ())
-+ {
-+ int regno = ii.get_src_mem_regno ();
-+ values[regno] = INVALID;
-+ for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (regno), k = j;
-+ j != r2r.end () && j->first == k->first;)
-+ {
-+ values[j->second] = INVALID;
-+ r2r.erase (j++);
-+ }
-+ }
-+
-+ if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) & ii.get_myuse ()))
-+ src = INVALID;
-+ else
-+ {
-+ src = SET_SRC(set);
-+ if (ii.is_src_mem () && src->volatil)
-+ src = INVALID;
-+ }
-+
-+ if (ii.get_dst_autoinc ())
-+ {
-+ int regno = ii.get_dst_mem_regno ();
-+ values[regno] = INVALID;
-+ for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (regno), k = j;
-+ j != r2r.end () && j->first == k->first;)
-+ {
-+ values[j->second] = INVALID;
-+ r2r.erase (j++);
-+ }
-+ }
-+
-+ if (src == INVALID || ii.get_src_op () || ii.get_dst_autoinc ())
-+ dest = INVALID;
-+ else
-+ dest = SET_DEST(set);
-+
-+ // track register values for now
-+ int dregno = ii.get_dst_regno ();
-+ int sregno = ii.get_src_regno ();
-+
-+ // track r2r
-+ if (dregno >= 0 && sregno >= 0)
-+ {
-+ r2r.insert (std::make_pair (dregno, sregno));
-+ r2r.insert (std::make_pair (sregno, dregno));
-+ }
-+
-+ if (sregno >= 0)
-+ {
-+ values[sregno] = dest;
-+ for (unsigned i = sregno + 1; i < END_REGNO (ii.get_src_reg ()); ++i)
-+ values[i] = INVALID;
-+ }
-+
-+ if (dregno >= 0)
-+ {
-+ // TODO: check for volatile sources
-+ values[dregno] = src;
-+ for (unsigned i = dregno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i)
-+ values[i] = INVALID;
-+
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
- /*
- * Some optimizations (e.g. propagate_moves) might result into an unused assignment behind the loop.
- * delete those insns.
-@@ -3301,11 +3484,13 @@ opt_shrink_stack_frame (void)
- static unsigned
- opt_elim_dead_assign (void)
+-__inline extern double
++__inline double
+ atan2 (double y, double x)
{
-+ track_regs ();
-+
- unsigned change_count = 0;
- for (int index = infos.size () - 1; index >= 0; --index)
- {
- insn_info & ii = infos[index];
-- if (!ii.get_dst_reg ())
-+ if (!ii.get_dst_reg () || ii.is_compare ())
- continue;
-
- rtx_insn * insn = ii.get_insn ();
-@@ -3319,8 +3504,23 @@ opt_elim_dead_assign (void)
- ++change_count;
- continue;
- }
-+ if (ii.get_src_op () == 0)
-+ {
-+ rtx cached_value = ii.get_value_for (ii.get_dst_regno ());
-+ rtx cached_value2 = 0;
-+ if (cached_value && cached_value != INVALID && REG_P(cached_value) && REGNO(cached_value) < 16)
-+ cached_value2 = ii.get_value_for (REGNO(cached_value));
-+ if (cached_value && cached_value != INVALID
-+ && (rtx_equal_p (cached_value, SET_SRC(set))
-+ || (cached_value2 && cached_value2 != INVALID && rtx_equal_p (cached_value2, SET_SRC(set)))))
-+ {
-+ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-
-- continue;
-+ }
-+ }
+ double pi, pi_over_2;
+@@ -187,7 +187,7 @@ atan2 (double y, double x)
}
- return change_count;
}
-@@ -3360,8 +3560,8 @@ opt_absolute (void)
-
- std::vector<unsigned> found;
- found.push_back (i);
-- unsigned base = ii.get_dst_addr ();
-- unsigned max = base;
-+ int base = ii.get_dst_addr ();
-+ int max = base;
- unsigned j = i + 1;
- for (; j < infos.size (); ++j)
- {
-@@ -3393,7 +3593,7 @@ opt_absolute (void)
-
- if (j_dst)
- {
-- unsigned addr = jj.get_dst_addr ();
-+ int addr = jj.get_dst_addr ();
- if (addr < base)
- {
- if (max - addr <= 0x7ffe)
-@@ -3413,7 +3613,7 @@ opt_absolute (void)
- }
- if (j_src)
- {
-- unsigned addr = jj.get_src_mem_addr ();
-+ int addr = jj.get_src_mem_addr ();
- if (addr < base)
- {
- if (max - addr <= 0x7ffe)
-@@ -3439,8 +3639,14 @@ opt_absolute (void)
- for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();)
- {
- insn_info & kk = infos[*k];
-- if (kk.get_dst_addr () - base > 0x7ffc)
-- found.erase (k);
-+ bool k_dst = kk.is_dst_mem () && (kk.has_dst_addr () || kk.get_dst_symbol ()) && !kk.has_dst_memreg ()
-+ && kk.get_dst_symbol () == with_symbol;
-+ bool k_src = kk.is_src_mem () && (kk.has_src_addr () || kk.get_src_symbol ()) && !kk.has_src_memreg ()
-+ && kk.get_src_symbol () == with_symbol;
-+ if (k_dst && kk.get_dst_addr () - base > 0x7ffc)
-+ found.erase (k++);
-+ else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
-+ found.erase (k++);
- else
- ++k;
- }
-
-From 09bb1d02257cbc120bb9f2fa8d4b49999662f328 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Mon, 5 Jun 2017 09:10:12 +0100
-Subject: [PATCH 161/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 54bc2fee3dce..cb00f5c9a36e 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170603-190132
-+20170605-091011
-
-From 9be210ab91c70ab5776d8e01fb4c63e8b7695a0f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 6 Jun 2017 16:56:04 +0200
-Subject: [PATCH 162/303] @I improve the algorithm to find redundant register
- loads
-
----
- gcc/bbb-opts.c | 280 +++++++++++++++++++++++++++++++--------------------------
- 1 file changed, 153 insertions(+), 127 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index e9a8df7d1c01..6fc53c674a4d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -116,6 +116,76 @@ enum proepis
- IN_CODE, IN_PROLOGUE, IN_EPILOGUE, IN_EPILOGUE_PARALLEL_POP
- };
-+class track_var
-+{
-+ rtx * values;
-+ unsigned * versions;
-+
-+public:
-+ track_var (track_var const * o = 0) :
-+ values ((rtx *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(rtx))), versions (
-+ (unsigned *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(unsigned)))
-+ {
-+ if (o)
-+ assign (o);
-+ }
-+
-+ rtx *
-+ get_values () const
-+ {
-+ return values;
-+ }
-+
-+ void
-+ set_version (unsigned regno, unsigned ver)
-+ {
-+ if (regno < FIRST_PSEUDO_REGISTER)
-+ versions[regno] = ver;
-+ }
-+
-+ void
-+ assign (track_var const * o) const
-+ {
-+ memcpy (values, o->values, FIRST_PSEUDO_REGISTER * sizeof(rtx));
-+ memcpy (versions, o->versions, FIRST_PSEUDO_REGISTER * sizeof(unsigned));
-+ }
-+
-+ /* only keep common values in both sides. */
-+ void
-+ merge (track_var * o)
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (values[i] && o->values[i] && rtx_equal_p (values[i], o->values[i]))
-+ {
-+ int code = GET_CODE(values[i]);
-+ if (code != CONST_INT && code != CONST_FIXED && code != CONST_DOUBLE && versions[i] != o->versions[i])
-+ values[i] = o->values[i] = 0;
-+ }
-+ else
-+ values[i] = o->values[i] = 0;
-+ }
-+ }
-+
-+ /* true if a merge would not change anything. */
-+ bool
-+ contains (track_var const * o) const
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (values[i] && o->values[i] && rtx_equal_p (values[i], o->values[i]))
-+ {
-+ int code = GET_CODE(values[i]);
-+ if (code != CONST_INT && code != CONST_FIXED && code != CONST_DOUBLE && versions[i] != o->versions[i])
-+ return false;
-+ }
-+ else if (values[i])
-+ return false;
-+ }
-+ return true;
-+ }
-+};
-+
- /* Information for each insn to detect alive registers. Enough for m68k.
- * Why a class? Maybe extend it for general usage.
- *
-@@ -125,7 +195,7 @@ class insn_info
+-__inline extern double
++__inline double
+ sinh (double x)
{
- rtx_insn * insn; // the insn
-
-- // usage flags
-+// usage flags
- unsigned myuse; // bit set if registers are used in this statement
- unsigned hard; // bit set if registers can't be renamed
- unsigned use; // bit set if registers are used in program flow
-@@ -135,7 +205,7 @@ class insn_info
-
- bool stack; // part of stack frame insns
-
-- // stuff to analyze insns
-+// stuff to analyze insns
- bool label;
- bool jump;
- bool call;
-@@ -168,8 +238,8 @@ class insn_info
- int dst_autoinc;
- int src_autoinc;
-
-- // values for all variables - if used
-- rtx * values;
-+// values for all variables - if used
-+ track_var * track;
-
- public:
- insn_info (rtx_insn * i = 0, enum proepis p = IN_CODE) :
-@@ -177,24 +247,12 @@ class insn_info
- false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus (false), src_op (
- (rtx_code) 0), src_ee (false), src_2nd (false), src_const (false), mode (VOIDmode), dst_reg (0), dst_mem_reg (
- 0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0), src_intval (0), src_mem_addr (
-- 0), visited (false), sp_offset (0), dst_autoinc (0), src_autoinc (0), values (0)
-+ 0), visited (false), sp_offset (0), dst_autoinc (0), src_autoinc (0), track (0)
- {
- }
+ double value;
+@@ -198,7 +198,7 @@ sinh (double x)
+ return value;
+ }
-- rtx *
-- get_values ();
--
-- void
-- set_values (rtx * v);
--
-- bool
-- merge_values (rtx * v);
--
-- bool
-- equal_values (rtx * v) const;
--
-- rtx
-- get_value_for (unsigned regno) const;
-+ track_var *
-+ get_track_var ();
+-__inline extern double
++__inline double
+ cosh (double x)
+ {
+ double value;
+@@ -209,7 +209,7 @@ cosh (double x)
+ return value;
+ }
- inline ptrdiff_t
- operator < (insn_info const & o) const
-@@ -744,65 +802,12 @@ class insn_info
- a5_to_a7 (rtx a7);
- };
+-__inline extern double
++__inline double
+ tanh (double x)
+ {
+ double value;
+@@ -220,7 +220,7 @@ tanh (double x)
+ return value;
+ }
--rtx *
--insn_info::get_values ()
-+track_var *
-+insn_info::get_track_var ()
+-__inline extern double
++__inline double
+ atanh (double x)
{
-- if (values)
-- return values;
--
-- values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx));
-- memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx));
-- return values;
--}
--
--void
--insn_info::set_values (rtx * v)
--{
-- if (!values)
-- values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx));
-- memcpy (values, v, FIRST_PSEUDO_REGISTER * sizeof(rtx));
--}
--
--static const rtx INVALID = (rtx) -1;
--
--bool
--insn_info::merge_values (rtx * v)
--{
-- bool r = false;
-- if (!values)
-- r = true, set_values (v);
-- else
-- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-- if (!values[i])
-- r = true, values[i] = v[i];
-- else if (values[i] != INVALID && v[i] && v[i] != INVALID && !rtx_equal_p (values[i], v[i]))
-- r = true, values[i] = INVALID;
-- return r;
--}
--
--bool
--insn_info::equal_values (rtx * v) const
--{
-- if (!values)
-- return false;
-- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-- if (values[i] && !v[i])
-- return false;
-- else if (v[i] && !values[i])
-- return false;
-- else if (values[i] == INVALID && v[i] != INVALID)
-- return false;
-- else if (!rtx_equal_p (values[i], v[i]))
-- return false;
-- return true;
--}
--
--rtx
--insn_info::get_value_for (unsigned regno) const
--{
-- if (!values || regno > 15)
-- return 0;
-- return values[regno];
-+ if (!track)
-+ track = new track_var ();
-+ return track;
+ double value;
+@@ -231,7 +231,7 @@ atanh (double x)
+ return value;
}
- void
-@@ -899,7 +904,7 @@ insn_info::scan_rtx (rtx x)
- unsigned d = def;
- scan_rtx (XVECEXP(x, i, j));
- use |= u;
-- myuse |= myuse;
-+ myuse |= mu;
- def |= d;
- }
- }
-@@ -1185,12 +1190,12 @@ insn_info::get_index () const
- return pos;
- }
+-__inline extern double
++__inline double
+ exp (double x)
+ {
+ double value;
+@@ -242,7 +242,7 @@ exp (double x)
+ return value;
+ }
-- // realloc happened...
-+// realloc happened...
- for (unsigned i = 0; i < infos.size (); ++i)
- if (infos[i].get_insn () == this->insn)
- return i;
+-__inline extern double
++__inline double
+ expm1 (double x)
+ {
+ double value;
+@@ -253,7 +253,7 @@ expm1 (double x)
+ return value;
+ }
-- // whoops!?
-+// whoops!?
- return 0;
+-__inline extern double
++__inline double
+ log (double x)
+ {
+ double value;
+@@ -264,7 +264,7 @@ log (double x)
+ return value;
}
-@@ -1201,7 +1206,7 @@ insn_info::plus_to_move (rtx_insn * newinsn)
- src_op = (rtx_code) 0;
- src_reg = XEXP(PATTERN (newinsn), 1);
- insn2info.insert (std::make_pair (insn, this));
-- // usage flags did not change
-+// usage flags did not change
+-__inline extern double
++__inline double
+ log1p (double x)
+ {
+ double value;
+@@ -275,7 +275,7 @@ log1p (double x)
+ return value;
}
- void
-@@ -1214,7 +1219,7 @@ insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
- insn2info.insert (std::make_pair (insn, this));
- insn2info.insert (std::make_pair (ii.insn, &ii));
+-__inline extern double
++__inline double
+ log10 (double x)
+ {
+ double value;
+@@ -286,7 +286,7 @@ log10 (double x)
+ return value;
+ }
-- // usage flags did not change
-+// usage flags did not change
+-__inline extern double
++__inline double
+ sqrt (double x)
+ {
+ double value;
+@@ -297,13 +297,13 @@ sqrt (double x)
+ return value;
}
- static
-@@ -1363,7 +1368,7 @@ clear (void)
- static bool
- is_reg_dead (unsigned regno, unsigned _pos)
+-__inline extern double
++__inline double
+ hypot (double x, double y)
{
-- // skip labels.
-+// skip labels.
- for (unsigned pos = _pos + 1; pos < infos.size (); ++pos)
- {
- insn_info & ii0 = infos[pos];
-@@ -2719,7 +2724,7 @@ opt_merge_add (void)
- static unsigned
- track_sp ()
+ return sqrt (x*x + y*y);
+ }
+
+-__inline extern double
++__inline double
+ pow (double x, double y)
{
-- // reset visited flags
-+// reset visited flags
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-@@ -2727,7 +2732,7 @@ track_sp ()
- ii.set_sp_offset (0);
+ if (x > 0)
+@@ -352,7 +352,7 @@ pow (double x, double y)
}
+ }
-- // add entry point
-+// add entry point
- std::set<unsigned> todo;
- todo.insert (0);
+-__inline extern double
++__inline double
+ fabs (double x)
+ {
+ double value;
+@@ -363,7 +363,7 @@ fabs (double x)
+ return value;
+ }
-@@ -3319,7 +3324,7 @@ opt_shrink_stack_frame (void)
- static unsigned
- track_regs ()
+-__inline extern double
++__inline double
+ ceil (double x)
{
-- // reset visited flags
-+// reset visited flags
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-@@ -3327,45 +3332,59 @@ track_regs ()
- ii.set_sp_offset (0);
- }
+ int rounding_mode, round_up;
+@@ -385,7 +385,7 @@ ceil (double x)
+ return value;
+ }
-- rtx * values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx)); // track register values
-+ update_label2jump ();
+-__inline extern double
++__inline double
+ floor (double x)
+ {
+ int rounding_mode, round_down;
+@@ -408,7 +408,7 @@ floor (double x)
+ return value;
+ }
-- // add entry point
-- std::set<unsigned> todo;
-- todo.insert (0);
-+// add entry point
-+ std::map<unsigned, track_var *> todo;
-+ todo.insert (std::make_pair (0, new track_var ()));
+-__inline extern double
++__inline double
+ rint (double x)
+ {
+ int rounding_mode, round_nearest;
+@@ -430,7 +430,7 @@ rint (double x)
+ return value;
+ }
- while (todo.begin () != todo.end ())
- {
-- unsigned startpos = *todo.begin ();
-+ unsigned startpos = todo.begin ()->first;
-+ track_var * const track = todo.begin ()->second;
- todo.erase (todo.begin ());
+-__inline extern double
++__inline double
+ fmod (double x, double y)
+ {
+ double value;
+@@ -442,7 +442,7 @@ fmod (double x, double y)
+ return value;
+ }
-- memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx));
--
-+ rtx * values = track->get_values ();
- // track register aliases: know which register refers to this slot
- // if a register changes, invalidate each referrer
- std::multimap<unsigned, unsigned> r2r;
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-- if (values[i] && values[i] != INVALID && REG_P(values[i]))
-+ if (values[i] && REG_P(values[i]))
- r2r.insert (std::make_pair (REGNO(values[i]), i));
+-__inline extern double
++__inline double
+ drem (double x, double y)
+ {
+ double value;
+@@ -454,7 +454,7 @@ drem (double x, double y)
+ return value;
+ }
-+ unsigned version = startpos;
-+
- for (unsigned index = startpos; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
+-__inline extern double
++__inline double
+ scalb (double x, int n)
+ {
+ double value;
+@@ -466,7 +466,7 @@ scalb (double x, int n)
+ return value;
+ }
- // already visited?
-- if (ii.is_visited () && ii.equal_values (values))
-+ if (ii.is_visited () && ii.get_track_var ()->contains (track))
- break;
+-__inline extern double
++__inline double
+ logb (double x)
+ {
+ double exponent;
+@@ -477,7 +477,7 @@ logb (double x)
+ return exponent;
+ }
-- // mark current insn_info and set sp_offset
-- ii.mark_visited ();
--
-- // do not optimize over labels
-+ // only keep common values at labels
- if (ii.is_label ())
- {
-- memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx));
-+ version = index;
-+ if (ii.is_visited ())
-+ {
-+ ii.get_track_var ()->merge (track);
-+ r2r.clear ();
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ if (values[i] && REG_P(values[i]))
-+ r2r.insert (std::make_pair (REGNO(values[i]), i));
-+ }
-+ else
-+ {
-+ ii.get_track_var ()->assign (track);
-+ ii.mark_visited ();
-+ }
- continue;
- }
+-__inline extern double
++__inline double
+ ldexp (double x, int n)
+ {
+ double value;
+@@ -489,7 +489,7 @@ ldexp (double x, int n)
+ return value;
+ }
-- ii.merge_values (values);
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
-+ ii.get_track_var ()->assign (track);
+-__inline extern double
++__inline double
+ frexp (double x, int *exp)
+ {
+ double float_exponent;
+@@ -514,7 +514,7 @@ frexp (double x, int *exp)
+ return mantissa;
+ }
- if (ii.is_compare ())
- continue;
-@@ -3381,7 +3400,7 @@ track_regs ()
- for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (i), k = j;
- j != r2r.end () && j->first == k->first;)
- {
-- values[j->second] = INVALID;
-+ values[j->second] = 0;
- r2r.erase (j++);
- }
- }
-@@ -3390,20 +3409,27 @@ track_regs ()
- if (ii.is_call ())
- continue;
+-__inline extern double
++__inline double
+ modf (double x, double *ip)
+ {
+ double temp;
+diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
+index 186436c42b77..9533e65ceaab 100644
+--- gcc/config/m68k/predicates.md
++++ gcc/config/m68k/predicates.md
+@@ -30,6 +30,10 @@
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST))
+ return 1;
++#ifdef TARGET_AMIGA
++ if (flag_pic >= 3 && amiga_is_const_pic_ref(op))
++ return 0;
++#endif
+ return general_operand (op, mode);
+ })
-+ rtx set = single_set (ii.get_insn ());
+diff --git a/gcc/config/m68k/t-amigaos b/gcc/config/m68k/t-amigaos
+new file mode 100755
+index 000000000000..bf9c5279d04f
+--- /dev/null
++++ gcc/config/m68k/t-amigaos
+@@ -0,0 +1,28 @@
++# Makefile fragment for AmigaOS target.
+
- // add all referred labels
- if (ii.is_jump ())
- {
-+ if (ANY_RETURN_P(ii.get_insn ()))
-+ break;
++# Extra object file linked to the cc1* executables.
++amigaos.o: $(srcdir)/config/m68k/amigaos.c $(CONFIG_H)
++ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+
- for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i)
-+ todo.insert (std::make_pair (i->second, new track_var (track)));
++# Additional target dependent options for compiling libgcc.a. This just
++# ensures that we don't compile libgcc* with anything other than a
++# fixed stack.
+
-+ if (set && GET_CODE(SET_SRC(set)) == IF_THEN_ELSE)
- {
-- todo.insert (i->second);
-- insn_info & jj = infos[i->second];
-- if (jj.merge_values (values))
-- ii.clear_visited ();
-+ version = index;
-+ continue;
- }
-- continue;
++#TARGET_LIBGCC2_CFLAGS = -mfixedstack
+
-+ // unconditional jump
-+ break;
- }
-
-- rtx set = single_set (ii.get_insn ());
- if (!set)
- continue;
-
-@@ -3411,38 +3437,38 @@ track_regs ()
- if (ii.get_src_autoinc ())
- {
- int regno = ii.get_src_mem_regno ();
-- values[regno] = INVALID;
-+ values[regno] = 0;
- for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (regno), k = j;
- j != r2r.end () && j->first == k->first;)
- {
-- values[j->second] = INVALID;
-+ values[j->second] = 0;
- r2r.erase (j++);
- }
- }
-
- if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) & ii.get_myuse ()))
-- src = INVALID;
-+ src = 0;
- else
- {
- src = SET_SRC(set);
- if (ii.is_src_mem () && src->volatil)
-- src = INVALID;
-+ src = 0;
- }
-
- if (ii.get_dst_autoinc ())
- {
- int regno = ii.get_dst_mem_regno ();
-- values[regno] = INVALID;
-+ values[regno] = 0;
- for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (regno), k = j;
- j != r2r.end () && j->first == k->first;)
- {
-- values[j->second] = INVALID;
-+ values[j->second] = 0;
- r2r.erase (j++);
- }
- }
-
-- if (src == INVALID || ii.get_src_op () || ii.get_dst_autoinc ())
-- dest = INVALID;
-+ if (src == 0 || ii.get_src_op () || ii.get_dst_autoinc ())
-+ dest = 0;
- else
- dest = SET_DEST(set);
-
-@@ -3460,19 +3486,20 @@ track_regs ()
- if (sregno >= 0)
- {
- values[sregno] = dest;
-+ track->set_version (sregno, version);
- for (unsigned i = sregno + 1; i < END_REGNO (ii.get_src_reg ()); ++i)
-- values[i] = INVALID;
-+ values[i] = 0;
- }
-
- if (dregno >= 0)
- {
-- // TODO: check for volatile sources
- values[dregno] = src;
-+ track->set_version (dregno, version);
- for (unsigned i = dregno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i)
-- values[i] = INVALID;
--
-+ values[i] = 0;
- }
- }
-+ delete track;
- }
- return 0;
- }
-@@ -3504,21 +3531,20 @@ opt_elim_dead_assign (void)
- ++change_count;
- continue;
- }
-- if (ii.get_src_op () == 0)
-+ if (ii.get_src_op () == 0 && ii.get_dst_reg ())
- {
-- rtx cached_value = ii.get_value_for (ii.get_dst_regno ());
-+ rtx cached_value = ii.get_track_var ()->get_values ()[ii.get_dst_regno ()];
- rtx cached_value2 = 0;
-- if (cached_value && cached_value != INVALID && REG_P(cached_value) && REGNO(cached_value) < 16)
-- cached_value2 = ii.get_value_for (REGNO(cached_value));
-- if (cached_value && cached_value != INVALID
-+ if (cached_value && REG_P(cached_value) && REGNO(cached_value) < FIRST_PSEUDO_REGISTER)
-+ cached_value2 = ii.get_track_var ()->get_values ()[REGNO(cached_value)];
-+ if (cached_value
- && (rtx_equal_p (cached_value, SET_SRC(set))
-- || (cached_value2 && cached_value2 != INVALID && rtx_equal_p (cached_value2, SET_SRC(set)))))
-+ || (cached_value2 && rtx_equal_p (cached_value2, SET_SRC(set)))))
- {
- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
- SET_INSN_DELETED(insn);
- ++change_count;
- continue;
--
- }
- }
- }
-
-From eaecabb03f08d5c95aea084f47753a8249c9170a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 7 Jun 2017 13:03:52 +0200
-Subject: [PATCH 163/303] @B enable eliminate dead assignments again, @B fix sp
- shrinking, @B disable stack frame removal for eh handlers
-
----
- gcc/bbb-opts.c | 71 +++++++++++++++++++++++++++++++++++-----------------------
- 1 file changed, 43 insertions(+), 28 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 6fc53c674a4d..4f14d0799ac4 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1505,21 +1505,29 @@ update_insn_infos (void)
- if (LABEL_P(insn))
- {
- /* work on all jumps referring to that label. */
-- for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
-- i != label2jump.end () && i->first == k->first; ++i)
-- {
-- i2i_iterator j = insn2info.find (i->second);
-- if (j != insn2info.end ())
-- {
-- unsigned index = j->second->get_index ();
-- insn_info & jj = infos[index];
-- if (!jj.is_visited () || !jj.contains (ii))
-- {
-- jj.updateWith (ii);
-- todo.insert (index);
-- }
-- }
-- }
-+ l2j_iterator i = label2jump.find (insn->u2.insn_uid);
++### begin-GG-local: dynamic libraries
++# Extra objects that get compiled and linked to collect2
+
-+ /* no jump to here -> mark all registers as hard regs.
-+ * This label is maybe used in an exception handler.
-+ * Marking as hard also avoids stack frame removal.
-+ */
-+ if (i == label2jump.end ())
-+ infos[pos + 1].make_hard ();
-+ else
-+ for (l2j_iterator k = i; i != label2jump.end () && i->first == k->first; ++i)
-+ {
-+ i2i_iterator j = insn2info.find (i->second);
-+ if (j != insn2info.end ())
-+ {
-+ unsigned index = j->second->get_index ();
-+ insn_info & jj = infos[index];
-+ if (!jj.is_visited () || !jj.contains (ii))
-+ {
-+ jj.updateWith (ii);
-+ todo.insert (index);
-+ }
-+ }
-+ }
-
- if (pos == start)
- pp.mark_visited ();
-@@ -3128,7 +3136,7 @@ opt_shrink_stack_frame (void)
- }
- else
- {
-- rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1));
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1 + clobbers.size ()));
- rtx plus;
-
- int x = 0;
-@@ -3137,7 +3145,7 @@ opt_shrink_stack_frame (void)
-
- unsigned l = 0;
- /* no add if a5 is used with pop */
-- if (!usea5 || i < prologueend)
-+ if (add1)
- {
- plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
- XVECEXP(parallel, 0, l) = gen_rtx_SET(a7, plus);
-@@ -3180,12 +3188,18 @@ opt_shrink_stack_frame (void)
- }
- }
-
-- for (unsigned k = 0; k < clobbers.size (); ++k)
-+ for (unsigned k = 0; k < clobbers.size (); ++k, ++l)
- {
- rtx clobber = clobbers[k];
-- XVECEXP(parallel, 0, l++) = clobber;
-+ XVECEXP(parallel, 0, l) = clobber;
- }
-- emit_insn_after (parallel, insn);
++EXTRA_COLLECT2_OBJS = amigacollect2.o
+
-+ rtx_insn * neu;
-+ if (i < prologueend)
-+ neu = emit_insn_after (parallel, insn);
-+ else
-+ neu = emit_insn_before (parallel, insn);
-+ ii.set_insn (neu);
- }
- SET_INSN_DELETED(insn);
- changed = 1;
-@@ -3517,20 +3531,21 @@ opt_elim_dead_assign (void)
- for (int index = infos.size () - 1; index >= 0; --index)
- {
- insn_info & ii = infos[index];
-- if (!ii.get_dst_reg () || ii.is_compare ())
-+ if (ii.in_proepi () || !ii.get_dst_reg () || ii.is_compare ())
- continue;
-
- rtx_insn * insn = ii.get_insn ();
- rtx set = single_set (insn);
- if (!set)
-+ continue;
-
-- if (ii.get_src_reg () && is_reg_dead (ii.get_dst_regno (), index))
-- {
-- log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]);
-- SET_INSN_DELETED(insn);
-- ++change_count;
-- continue;
-- }
-+ if (ii.get_dst_reg () && is_reg_dead (ii.get_dst_regno (), index))
-+ {
-+ log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
- if (ii.get_src_op () == 0 && ii.get_dst_reg ())
- {
- rtx cached_value = ii.get_track_var ()->get_values ()[ii.get_dst_regno ()];
-
-From 9dad7c865fe3b09382759e1b35f29d577948f88d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 8 Jun 2017 15:05:24 +0200
-Subject: [PATCH 164/303] @B added a workaround for shared CLOBBERS (argh\!),
- @B mark sp as used in epilogue to avoid elimination of sp corrections, @B
- defs with mode size < 4 are now always an use too
-
----
- gcc/bbb-opts.c | 25 +++++++++++++++++++++----
- 1 file changed, 21 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 4f14d0799ac4..9825b55a1ea7 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1121,7 +1121,15 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- }
- else if (fmt[i] == 'E')
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-- temp_reg_rename (loc, XVECEXP(x, i, j), oldregno, newregno);
-+ {
-+ rtx z = XVECEXP(x, i, j);
-+ if (GET_CODE(z) == CLOBBER)
-+ {
-+ /* workaround for shared clobbers. */
-+ XVECEXP(x, i, j) = z = gen_rtx_CLOBBER(GET_MODE(z), XEXP(z, 0));
-+ }
-+ temp_reg_rename (loc, z, oldregno, newregno);
-+ }
- }
- }
-
-@@ -1484,6 +1492,10 @@ update_insn_infos (void)
-
- enum proepis proepi = ii.in_proepi ();
-
-+ // mark sp reg as used.
-+ if (proepi >= IN_EPILOGUE)
-+ ii.mark_use (STACK_POINTER_REGNUM), infos[start].mark_use (STACK_POINTER_REGNUM);
++# Build supplimentary AmigaOS target support file for collect2
++amigacollect2.o: amigacollect2.c
++ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
++ -DA2IXDIR_PREFIX=\"$(prefix)/share/a2ixlibrary\" $< $(OUTPUT_OPTION)
++### end-GG-local
+
- for (int pos = start; pos >= 0; --pos)
- {
- insn_info & pp = infos[pos];
-@@ -1578,6 +1590,10 @@ update_insn_infos (void)
- NOTICE_UPDATE_CC(PATTERN (insn), insn);
- if (cc_status.value1 || cc_status.value2)
- use.mark_def (FIRST_PSEUDO_REGISTER);
-+
-+ // also check mode size if < 4, it's also a def.
-+ if (ii.get_dst_reg () && GET_MODE_SIZE(ii.get_mode()) < 4)
-+ use.mark_def (ii.get_dst_regno ());
- }
-
- /* mark not renameable in prologue/epilogue. */
-@@ -3696,7 +3712,8 @@ opt_absolute (void)
- {
- unsigned regno = bit2regno (freemask);
- if (with_symbol)
-- log ("(b) modifying %d symbol addresses using %s\n", found.size (), reg_names[regno]);
-+ log ("(b) modifying %d symbol addresses for %s using %s\n", found.size (),
-+ with_symbol->u.block_sym.fld[0].rt_str, reg_names[regno]);
- else
- log ("(b) modifying %d absolute addresses using %s\n", found.size (), reg_names[regno]);
-
-@@ -3843,10 +3860,10 @@ namespace
- if (do_merge_add && opt_merge_add ())
- done = 0;
-
-- if (do_elim_dead_assign && opt_elim_dead_assign ())
-+ if (do_absolute && opt_absolute ())
- done = 0, update_insns ();
-
-- if (do_absolute && opt_absolute ())
-+ if (do_elim_dead_assign && opt_elim_dead_assign ())
- done = 0, update_insns ();
-
- if (do_bb_reg_rename)
-
-From b6bf8403f6febb237c2ae37474c97bb989c40f60 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 9 Jun 2017 13:41:35 +0200
-Subject: [PATCH 165/303] @B mark all returns and jumps (in calls) sp using, @B
- keep volatile flag in absolute_base conversion
-
----
- gcc/bbb-opts.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 9825b55a1ea7..c8d29013f981 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1291,7 +1291,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- rtx set = single_set (get_insn ());
- rtx src = SET_SRC(set);
- rtx dst = SET_DEST(set);
--
-+ bool vola = src->volatil;
- rtx pattern;
- rtx reg = gen_raw_REG (SImode, regno);
-
-@@ -1348,6 +1348,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- }
-
- pattern = gen_rtx_SET(dst, src);
-+ src->volatil = vola;
-
- SET_INSN_DELETED(insn);
- insn = emit_insn_after (pattern, insn);
-@@ -1661,6 +1662,9 @@ update_insns ()
- {
- if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
- {
-+ if (ANY_RETURN_P(PATTERN (insn)))
-+ ii.set_proepi(IN_EPILOGUE);
-+
- scan_starts.insert (infos.size () - 1);
- inproepilogue = IN_CODE;
- rtx set = single_set (insn);
-@@ -1696,6 +1700,7 @@ update_insns ()
- {
- rtx label = XEXP(ref, 0);
- label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ ii.set_proepi(IN_EPILOGUE);
- }
- }
- }
-@@ -1735,6 +1740,8 @@ update_insns ()
- }
- else if (CALL_P(insn))
- {
-+ if (insn->jump)
-+ ii.set_proepi(IN_EPILOGUE);
- ii.mark_call ();
- if (inproepilogue)
- {
-
-From d8619150fdaca31cc31de96fe94f4e4bd212fe76 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Fri, 9 Jun 2017 15:00:32 +0100
-Subject: [PATCH 166/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index cb00f5c9a36e..ba919c60d861 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170605-091011
-+20170609-145423
-
-From d485949ff4cc8d323dbf9b4810fd379ccbe98cfc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 11 Jun 2017 13:04:22 +0200
-Subject: [PATCH 167/303] @R excluded fpgnulib.c from libgcc
-
----
- libgcc/config.host | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/libgcc/config.host b/libgcc/config.host
-index f456ff689ad9..1478faa2b027 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -817,8 +817,7 @@ m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
- m68k-*-amiga*)
-- tmake_file="$tmake_file
--# m68k/t-floatlib"
-+# tmake_file="$tmake_file m68k/t-floatlib"
- ;;
- m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
-
-From 4ed9bba08719add41aec99292e4dc315699f6111 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 11 Jun 2017 12:06:59 +0100
-Subject: [PATCH 168/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index ba919c60d861..e7d6b1e3aa50 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170609-145423
-+20170611-120626
-
-From cd1e07319580d7ea753d8202fe8a03aec19a9b3b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 11 Jun 2017 22:40:39 +0200
-Subject: [PATCH 169/303] @B fix linking add -lstubs again
-
----
- gcc/config/m68k/m68kamigaos.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 8a25f8cbfdfb..50859a4c283f 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -487,7 +487,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- #define LIBGCC_IXEMUL_SPEC ""
- #define LIBGCC_LIBNIX_SPEC "-lnix -fl libnix " \
- "%{mcrt=*:-l%*} " \
-- "%{!mcrt=*:-lnix20}"
-+ "%{!mcrt=*:-lnix20} -lstubs"
- #define LIBGCC_CLIB2_SPEC "-lc"
- #define LIBGCC_SPEC "-lgcc " \
- "%{noixemul:%(libgcc_libnix)} " \
-
-From 40fa6300271e5cd3d886f54d5696c6e748ecdc52 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 11 Jun 2017 22:41:23 +0200
-Subject: [PATCH 170/303] @B lock a4 if baserel, @B better invalidation in
- register tracking
-
----
- gcc/bbb-opts.c | 168 +++++++++++++++++++++++++++++++++------------------------
- 1 file changed, 98 insertions(+), 70 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index c8d29013f981..9a0a3ac80e43 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1126,7 +1126,7 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- if (GET_CODE(z) == CLOBBER)
- {
- /* workaround for shared clobbers. */
-- XVECEXP(x, i, j) = z = gen_rtx_CLOBBER(GET_MODE(z), XEXP(z, 0));
-+ XVECEXP(x, i, j) = z = gen_rtx_CLOBBER (GET_MODE(z), XEXP(z, 0));
- }
- temp_reg_rename (loc, z, oldregno, newregno);
- }
-@@ -1268,7 +1268,7 @@ insn_info::a5_to_a7 (rtx a7)
- rtx set = single_set (insn);
- if (set)
- {
-- SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC(SImode, a7));
-+ SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC (SImode, a7));
- return;
- }
- }
-@@ -1304,7 +1304,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- if (base == addr)
- dst = gen_rtx_MEM (mode, reg);
- else
-- dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-+ dst = gen_rtx_MEM (mode, gen_rtx_PLUS (SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-
- dst_mem_reg = reg;
- dst_mem = true;
-@@ -1322,13 +1322,13 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- if (base == addr)
- src = gen_rtx_MEM (mode, reg);
- else
-- src = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-+ src = gen_rtx_MEM (mode, gen_rtx_PLUS (SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-
- /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */
- if (src_op)
- {
- if (src_ee)
-- src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
-+ src = gen_rtx_fmt_ee (src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
- else
- {
- if (src_op == SIGN_EXTEND)
-@@ -1336,7 +1336,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- PUT_MODE_RAW(src, mode == SImode ? HImode : mode == HImode ? QImode : SImode);
- src->call = 1;
- }
-- src = gen_rtx_fmt_e(src_op, mode, src);
-+ src = gen_rtx_fmt_e (src_op, mode, src);
- }
- }
-
-@@ -1347,7 +1347,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- }
- }
-
-- pattern = gen_rtx_SET(dst, src);
-+ pattern = gen_rtx_SET (dst, src);
- src->volatil = vola;
-
- SET_INSN_DELETED(insn);
-@@ -1485,6 +1485,8 @@ update_insn_infos (void)
- if (todo.begin () == todo.end ())
- todo.insert (infos.size () - 1);
-
-+ bool locka4 = flag_pic >= 3;
++# Support for building multiple version of libgcc, libquadmath, libobjc and libstdc++-v3
++MULTILIB_OPTIONS = m68020 fbaserel/fbaserel32
++MULTILIB_DIRNAMES = libm020 libb libb32
++MULTILIB_EXTRA_OPTS = noixemul
++MULTILIB_EXCEPTIONS = fbaserel32
+\ No newline at end of file
+diff --git a/gcc/config/m68k/x-amigaos b/gcc/config/m68k/x-amigaos
+new file mode 100755
+index 000000000000..a8f60b80f9f4
+--- /dev/null
++++ gcc/config/m68k/x-amigaos
+@@ -0,0 +1,104 @@
++# Makefile fragment for AmigaOS host
+
- while (!todo.empty ())
- {
- int start = *todo.begin ();
-@@ -1563,6 +1565,8 @@ update_insn_infos (void)
- rtx pattern = PATTERN (insn);
- insn_info use (insn);
- use.scan ();
-+ if (locka4 && (use.get_myuse () & (1 << PIC_REG)))
-+ use.mark_hard (PIC_REG);
-
- /* do not mark a node as visited, if it's in epilogue and not yet visited. */
- if (CALL_P(insn) || JUMP_P(insn))
-@@ -1663,7 +1667,7 @@ update_insns ()
- if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
- {
- if (ANY_RETURN_P(PATTERN (insn)))
-- ii.set_proepi(IN_EPILOGUE);
-+ ii.set_proepi (IN_EPILOGUE);
-
- scan_starts.insert (infos.size () - 1);
- inproepilogue = IN_CODE;
-@@ -1700,7 +1704,7 @@ update_insns ()
- {
- rtx label = XEXP(ref, 0);
- label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-- ii.set_proepi(IN_EPILOGUE);
-+ ii.set_proepi (IN_EPILOGUE);
- }
- }
- }
-@@ -1741,7 +1745,7 @@ update_insns ()
- else if (CALL_P(insn))
- {
- if (insn->jump)
-- ii.set_proepi(IN_EPILOGUE);
-+ ii.set_proepi (IN_EPILOGUE);
- ii.mark_call ();
- if (inproepilogue)
- {
-@@ -1860,6 +1864,11 @@ opt_reg_rename (void)
-
- /* get the mask for free registers. */
- unsigned mask = ii.get_free_mask ();
++# 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.
+
-+ /* do not use a4 if compiling baserel */
-+ if (flag_pic >= 3)
-+ mask &= ~(1 << PIC_REG);
++SYSTEM_HEADER_DIR = $(prefix)/include
+
- if (!mask)
- continue;
-
-@@ -2300,8 +2309,8 @@ opt_propagate_moves ()
-
- for (unsigned k = 0; k < jump_out.size (); ++k)
- {
-- rtx neu = gen_rtx_SET(
-- dstj, gen_rtx_PLUS(Pmode, dsti, gen_rtx_CONST_INT(Pmode, fixups[k])));
-+ rtx neu = gen_rtx_SET (
-+ dstj, gen_rtx_PLUS (Pmode, dsti, gen_rtx_CONST_INT (Pmode, fixups[k])));
- emit_insn_after (neu, jump_out[k]);
- }
- }
-@@ -2377,7 +2386,7 @@ opt_strcpy ()
- int num_clobbers_to_add = 0;
- int insn_code_number;
-
-- rtx pattern = gen_rtx_SET(SET_DEST(single_set(reg2x)), SET_SRC(single_set (x2reg)));
-+ rtx pattern = gen_rtx_SET (SET_DEST(single_set (reg2x)), SET_SRC(single_set (x2reg)));
- rtx_insn * newinsn = make_insn_raw (pattern);
- insn_code_number = recog (PATTERN (newinsn), newinsn, &num_clobbers_to_add);
- if (insn_code_number >= 0 && check_asm_operands (PATTERN (newinsn)))
-@@ -2489,10 +2498,10 @@ opt_commute_add_move (void)
- if (!REG_P(memreg) || REGNO(memreg) != REGNO(reg1src))
- continue;
-
-- rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1dst);
-+ rtx pinc = gen_rtx_POST_INC (GET_MODE(dst), reg1dst);
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
-- rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(reg1dst, reg1src));
-+ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET (reg1dst, reg1src));
- if (recog (PATTERN (newinsn), newinsn, 0) < 0 || !check_asm_operands (PATTERN (newinsn)))
- continue;
-
-@@ -2620,9 +2629,9 @@ opt_const_cmp_to_sub (void)
- {
- rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
- /* create the sub statement. */
-- rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), intval));
-+ rtx sub = gen_rtx_PLUS (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), intval));
-
-- rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub));
-+ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET (copyreg, sub));
-
- int num_clobbers_to_add = 0;
- int insn_code_number = recog (PATTERN (subinsn), subinsn, &num_clobbers_to_add);
-@@ -2639,8 +2648,8 @@ opt_const_cmp_to_sub (void)
- subinsn = emit_insn_before (PATTERN (subinsn), i1.get_insn ());
- i1.set_insn (subinsn);
-
-- rtx neu = gen_rtx_SET(cc0_rtx,
-- gen_rtx_COMPARE(i1.get_mode (), copyreg, gen_rtx_CONST_INT(i1.get_mode (), 0)));
-+ rtx neu = gen_rtx_SET (cc0_rtx,
-+ gen_rtx_COMPARE (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), 0)));
-
- emit_insn_before (neu, i2.get_insn ());
-
-@@ -2661,8 +2670,8 @@ opt_const_cmp_to_sub (void)
- /* still a compare with 0 -> insert the sub. */
- rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
- /* create the sub statement. */
-- rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, c);
-- rtx set = gen_rtx_SET(copyreg, sub);
-+ rtx sub = gen_rtx_PLUS (i1.get_mode (), copyreg, c);
-+ rtx set = gen_rtx_SET (copyreg, sub);
- emit_insn_before (set, pp.get_insn ());
- }
- else
-@@ -2734,7 +2743,7 @@ opt_merge_add (void)
- rtx set = PATTERN (insn0);
-
- // convert lea (-1,a0),a1 into move.l a0,a1
-- rtx_insn * newins0 = make_insn_raw (gen_rtx_SET(XEXP(set, 0), XEXP(XEXP(set, 1), 0)));
-+ rtx_insn * newins0 = make_insn_raw (gen_rtx_SET (XEXP(set, 0), XEXP(XEXP(set, 1), 0)));
- add_insn_after (newins0, insn0, 0);
- SET_INSN_DELETED(insn0);
- // update infos accordingly
-@@ -3142,24 +3151,24 @@ opt_shrink_stack_frame (void)
- if (i < prologueend)
- {
- /* push */
-- rtx dec = gen_rtx_PRE_DEC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
-+ rtx dec = gen_rtx_PRE_DEC (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
-- rtx set = gen_rtx_SET(mem, reg);
-+ rtx set = gen_rtx_SET (mem, reg);
- emit_insn_after (set, insn);
- }
- else
- {
- /* pop */
-- rtx dec = gen_rtx_POST_INC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
-+ rtx dec = gen_rtx_POST_INC (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
-- rtx set = gen_rtx_SET(reg, mem);
-+ rtx set = gen_rtx_SET (reg, mem);
- emit_insn_before (set, insn);
- }
- }
- }
- else
- {
-- rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1 + clobbers.size ()));
-+ rtx parallel = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (regs.size () + add1 + clobbers.size ()));
- rtx plus;
-
- int x = 0;
-@@ -3170,8 +3179,8 @@ opt_shrink_stack_frame (void)
- /* no add if a5 is used with pop */
- if (add1)
- {
-- plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-- XVECEXP(parallel, 0, l) = gen_rtx_SET(a7, plus);
-+ plus = gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-+ XVECEXP(parallel, 0, l) = gen_rtx_SET (a7, plus);
- ++l;
- }
-
-@@ -3183,10 +3192,10 @@ opt_shrink_stack_frame (void)
- if (i < prologueend)
- {
- /* push */
-- plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, -x));
-+ plus = gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, -x));
- x -= REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-- rtx set = gen_rtx_SET(mem, regs[k]);
-+ rtx set = gen_rtx_SET (mem, regs[k]);
- XVECEXP(parallel, 0, l) = set;
- }
- else
-@@ -3195,17 +3204,17 @@ opt_shrink_stack_frame (void)
- if (usea5)
- {
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-- plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
-+ plus = gen_rtx_PLUS (SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-- rtx set = gen_rtx_SET(regs[k], mem);
-+ rtx set = gen_rtx_SET (regs[k], mem);
- XVECEXP(parallel, 0, l) = set;
- }
- else
- {
-- plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
-+ plus = x ? gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-- rtx set = gen_rtx_SET(regs[k], mem);
-+ rtx set = gen_rtx_SET (regs[k], mem);
- XVECEXP(parallel, 0, l) = set;
- }
- }
-@@ -3297,8 +3306,8 @@ opt_shrink_stack_frame (void)
- if (ii.in_proepi () >= IN_EPILOGUE && ii.get_sp_offset () != 0)
- {
- log ("(f) adjusting exit sp\n");
-- rtx pattern = gen_rtx_SET(a7,
-- gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT(SImode, - ii.get_sp_offset())));
-+ rtx pattern = gen_rtx_SET (
-+ a7, gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, -ii.get_sp_offset ())));
- emit_insn_before (pattern, ii.get_insn ());
- }
- }
-@@ -3316,7 +3325,7 @@ opt_shrink_stack_frame (void)
- rtx pattern = PATTERN (ii.get_insn ());
- unsigned sz = XVECLEN(pattern, 0);
-
-- rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (sz + 1));
-+ rtx parallel = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (sz + 1));
- unsigned n = 0;
- for (unsigned j = 0; j < sz; ++j)
- {
-@@ -3338,8 +3347,8 @@ opt_shrink_stack_frame (void)
-
- rtx a = copy_reg (a7, -1);
- a->frame_related = 1;
-- rtx plus = gen_rtx_PLUS(SImode, a, gen_rtx_CONST_INT (SImode, regs_total_size));
-- rtx set = gen_rtx_SET(a, plus);
-+ rtx plus = gen_rtx_PLUS (SImode, a, gen_rtx_CONST_INT (SImode, regs_total_size));
-+ rtx set = gen_rtx_SET (a, plus);
- XVECEXP(parallel, 0, 0) = set;
- SET_INSN_DELETED(ii.get_insn ());
- ii.set_insn (emit_insn_after (parallel, ii.get_insn ()));
-@@ -3382,12 +3391,18 @@ track_regs ()
- todo.erase (todo.begin ());
-
- rtx * values = track->get_values ();
-- // track register aliases: know which register refers to this slot
-- // if a register changes, invalidate each referrer
-- std::multimap<unsigned, unsigned> r2r;
-- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-- if (values[i] && REG_P(values[i]))
-- r2r.insert (std::make_pair (REGNO(values[i]), i));
-+ // track register aliases: know which register is used in what slot
-+ // if a register changes, invalidate each slot
-+ std::multimap<unsigned, unsigned> reg2slot;
-+ for (unsigned slot = 0; slot < FIRST_PSEUDO_REGISTER; ++slot)
-+ if (values[slot])
-+ {
-+ insn_info vv;
-+ vv.scan_rtx (values[slot]);
-+ for (unsigned regno = 0, m = vv.get_myuse (); m; ++regno, m >>= 1)
-+ if (m & 1)
-+ reg2slot.insert (std::make_pair (regno, slot));
-+ }
-
- unsigned version = startpos;
-
-@@ -3406,10 +3421,16 @@ track_regs ()
- if (ii.is_visited ())
- {
- ii.get_track_var ()->merge (track);
-- r2r.clear ();
-- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-- if (values[i] && REG_P(values[i]))
-- r2r.insert (std::make_pair (REGNO(values[i]), i));
-+ reg2slot.clear ();
-+ for (unsigned slot = 0; slot < FIRST_PSEUDO_REGISTER; ++slot)
-+ if (values[slot])
-+ {
-+ insn_info vv;
-+ vv.scan_rtx (values[slot]);
-+ for (unsigned regno = 0, m = vv.get_myuse (); m; ++regno, m >>= 1)
-+ if (m & 1)
-+ reg2slot.insert (std::make_pair (regno, slot));
-+ }
- }
- else
- {
-@@ -3429,16 +3450,16 @@ track_regs ()
- unsigned def = ii.get_def ();
- if (def)
- {
-- for (int i = 0; i < 16; ++i)
-- if ((1 << i) & def)
-+ for (int regno = 0; regno < 16; ++regno)
-+ if ((1 << regno) & def)
- {
-- values[i] = 0;
-+ values[regno] = 0;
- // invalidate all referring registers
-- for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (i), k = j;
-- j != r2r.end () && j->first == k->first;)
-+ for (std::multimap<unsigned, unsigned>::iterator j = reg2slot.find (regno), k = j;
-+ j != reg2slot.end () && j->first == k->first;)
- {
- values[j->second] = 0;
-- r2r.erase (j++);
-+ reg2slot.erase (j++);
- }
- }
- }
-@@ -3475,11 +3496,11 @@ track_regs ()
- {
- int regno = ii.get_src_mem_regno ();
- values[regno] = 0;
-- for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (regno), k = j;
-- j != r2r.end () && j->first == k->first;)
-+ for (std::multimap<unsigned, unsigned>::iterator j = reg2slot.find (regno), k = j;
-+ j != reg2slot.end () && j->first == k->first;)
- {
- values[j->second] = 0;
-- r2r.erase (j++);
-+ reg2slot.erase (j++);
- }
- }
-
-@@ -3496,11 +3517,11 @@ track_regs ()
- {
- int regno = ii.get_dst_mem_regno ();
- values[regno] = 0;
-- for (std::multimap<unsigned, unsigned>::iterator j = r2r.find (regno), k = j;
-- j != r2r.end () && j->first == k->first;)
-+ for (std::multimap<unsigned, unsigned>::iterator j = reg2slot.find (regno), k = j;
-+ j != reg2slot.end () && j->first == k->first;)
- {
- values[j->second] = 0;
-- r2r.erase (j++);
-+ reg2slot.erase (j++);
- }
- }
-
-@@ -3513,11 +3534,18 @@ track_regs ()
- int dregno = ii.get_dst_regno ();
- int sregno = ii.get_src_regno ();
-
-- // track r2r
-- if (dregno >= 0 && sregno >= 0)
-+ // track reg2slot
-+ if (dregno >= 0)
- {
-- r2r.insert (std::make_pair (dregno, sregno));
-- r2r.insert (std::make_pair (sregno, dregno));
-+ for (unsigned regno = 0, m = ii.get_myuse (); m; ++regno, m >>= 1)
-+ if (m & 1)
-+ reg2slot.insert (std::make_pair (regno, dregno));
++# 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).
+
-+ if (sregno >= 0)
-+ {
-+ reg2slot.insert (std::make_pair (dregno, sregno));
-+ reg2slot.insert (std::make_pair (sregno, dregno));
-+ }
- }
-
- if (sregno >= 0)
-@@ -3738,14 +3766,14 @@ opt_absolute (void)
- if (with_symbol)
- {
- if (base)
-- lea = gen_rtx_SET(
-+ lea = gen_rtx_SET (
- gen_raw_REG (SImode, regno),
-- gen_rtx_CONST(SImode, gen_rtx_PLUS(SImode, with_symbol, gen_rtx_CONST_INT (SImode, base))));
-+ gen_rtx_CONST (SImode, gen_rtx_PLUS (SImode, with_symbol, gen_rtx_CONST_INT (SImode, base))));
- else
-- lea = gen_rtx_SET(gen_raw_REG (SImode, regno), with_symbol);
-+ lea = gen_rtx_SET (gen_raw_REG (SImode, regno), with_symbol);
- }
- else
-- lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
-+ lea = gen_rtx_SET (gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
- rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
- insn_info nn (insn);
- nn.set_use (current_use);
-
-From 2950e164bd5d21b9654d111811ebb4bf75d9d618 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 11 Jun 2017 21:58:31 +0100
-Subject: [PATCH 171/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index e7d6b1e3aa50..be3338d16f6c 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170611-120626
-+20170611-215803
-
-From 40d1ade0abfaae48c16daacb5baf2a23a56f3473 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 12 Jun 2017 13:14:52 +0200
-Subject: [PATCH 172/303] @B fix redundand load elimination: evaluate multiple
- jumps to the same label correctly
-
----
- gcc/bbb-opts.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 9a0a3ac80e43..41b384b04cc6 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3381,7 +3381,7 @@ track_regs ()
- update_label2jump ();
-
- // add entry point
-- std::map<unsigned, track_var *> todo;
-+ std::multimap<unsigned, track_var *> todo;
- todo.insert (std::make_pair (0, new track_var ()));
-
- while (todo.begin () != todo.end ())
-@@ -3411,7 +3411,7 @@ track_regs ()
- insn_info & ii = infos[index];
-
- // already visited?
-- if (ii.is_visited () && ii.get_track_var ()->contains (track))
-+ if (index != startpos && ii.is_visited () && ii.get_track_var ()->contains (track))
- break;
-
- // only keep common values at labels
-
-From d56d8369cfbc4f2db520ec76ba22479ab637c5bd Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Mon, 12 Jun 2017 13:45:19 +0100
-Subject: [PATCH 173/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index be3338d16f6c..5d6c1ddcaf32 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170611-215803
-+20170612-134455
-
-From 356944afa320b13bbe8b650404dfae48880851a7 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 13 Jun 2017 14:32:12 +0200
-Subject: [PATCH 174/303] @B fix link order
-
----
- gcc/config/m68k/m68kamigaos.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 50859a4c283f..beac496ab148 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -462,7 +462,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{!p:%{!pg:-lc -lamiga -lc}} " \
- "%{p:-lc_p} %{pg:-lc_p}"
- #define LIB_LIBNIX_SPEC \
-- "-lnixmain -lnix -lstubs " \
-+ "-lnixmain -lnix " \
- "%{mcrt=*:-l%*} " \
- "%{!mcrt=*:-lnix20} " \
- "-lamiga " \
-
-From 7ec741afa4116beca5641b8f14f26c71c7ceb92d Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Tue, 13 Jun 2017 16:01:25 +0100
-Subject: [PATCH 175/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 5d6c1ddcaf32..bbab26fe7028 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170612-134455
-+20170613-160057
-
-From 91689b4bf59a1b051b8b137ccaad5df5b6fbae69 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 14 Jun 2017 22:33:56 +0200
-Subject: [PATCH 176/303] @N added opt_autoinc - replace offsets with auto incs
-
----
- gcc/bbb-opts.c | 308 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 270 insertions(+), 38 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 41b384b04cc6..23d8fdb582c3 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -439,6 +439,18 @@ class insn_info
- return dst_mem_reg ? REGNO(dst_mem_reg) : -1;
- }
-
-+ inline rtx
-+ get_src_mem_reg () const
-+ {
-+ return src_mem_reg;
-+ }
++#RESIDENT = -m68020 -resident32
+
-+ inline rtx
-+ get_dst_mem_reg () const
-+ {
-+ return dst_mem_reg;
-+ }
++# 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.
+
- inline int
- get_src_intval () const
- {
-@@ -762,6 +774,12 @@ class insn_info
- void
- scan_rtx (rtx);
-
-+ void
-+ make_post_inc (int regno);
++XCFLAGS = -mstackextend $(RESIDENT)
+
-+ void
-+ auto_inc_fixup (int regno, int size);
++# AmigaOS supports "AmigaGuide(R)" hypertext files. For GCC, these are
++# build with a custom "makeinfo".
+
- /* return bits for alternate free registers. */
- unsigned
- get_free_mask () const
-@@ -802,6 +820,64 @@ class insn_info
- a5_to_a7 (rtx a7);
- };
-
-+void
-+insn_info::make_post_inc (int regno)
-+{
-+ // convert into POST_INC
-+// debug_rtx (insn);
-+ rtx set = single_set (insn);
-+ rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-+ rtx reg = XEXP(mem, 0);
-+ XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
-+// debug_rtx (insn);
++# Arrange for guides to be build with GCC, in the build directory.
+
-+ (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
-+}
++### begin-GG-local: gcc-amigaos
++#EXTRA_DOC_TARGETS = guide gcc-amigaos-doc
++### end-GG-local
+
-+void
-+insn_info::auto_inc_fixup (int regno, int size)
-+{
-+// debug_rtx (insn);
++# Actually build guides
+
-+ rtx set = single_set (insn);
++guide:: doc/cpp.guide doc/gcc.guide doc/gccint.guide \
++ doc/gccinstall.guide doc/cppinternals.guide
+
-+ if (is_compare ())
-+ set = SET_SRC(set);
++doc/cpp.guide: $(TEXI_CPP_FILES)
++doc/gcc.guide: $(TEXI_GCC_FILES)
++doc/gccint.guide: $(TEXI_GCCINT_FILES)
++doc/cppinternals.guide: $(TEXI_CPPINT_FILES)
+
-+ // add to register
-+ if (get_src_regno () == regno)
-+ {
-+ rtx src = SET_SRC(set);
-+ if (get_src_intval () == size)
-+ {
-+ src_intval = 0;
-+ src_plus = false;
-+ SET_SRC(set) = XEXP(src, 0);
-+ }
-+ else
-+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
-+ }
-+ else
-+ {
-+ rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-+ // goto mem if there is an op
-+ if (get_src_mem_regno () == regno && src_op)
-+ mem = XEXP(mem, 1);
++doc/%.guide: %.texi
++ if [ x$(BUILD_INFO) = xinfo ]; then \
++ $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \
++ -I $(docdir)/include -o $@ $<; \
++ fi
+
-+ rtx plus = XEXP(mem, 0);
-+ if ((get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) == size)
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) = 0;
-+ (get_dst_mem_regno () == regno ? dst_plus : src_plus) = false;
-+ }
-+ else
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)),
-+ (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) -= size);
-+ }
-+// debug_rtx (insn);
-+}
++# 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
+
- track_var *
- insn_info::get_track_var ()
- {
-@@ -1126,7 +1202,7 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- if (GET_CODE(z) == CLOBBER)
- {
- /* workaround for shared clobbers. */
-- XVECEXP(x, i, j) = z = gen_rtx_CLOBBER (GET_MODE(z), XEXP(z, 0));
-+ XVECEXP(x, i, j) = z = gen_rtx_CLOBBER(GET_MODE(z), XEXP(z, 0));
- }
- temp_reg_rename (loc, z, oldregno, newregno);
- }
-@@ -1268,7 +1344,7 @@ insn_info::a5_to_a7 (rtx a7)
- rtx set = single_set (insn);
- if (set)
- {
-- SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC (SImode, a7));
-+ SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC(SImode, a7));
- return;
- }
- }
-@@ -1304,7 +1380,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- if (base == addr)
- dst = gen_rtx_MEM (mode, reg);
- else
-- dst = gen_rtx_MEM (mode, gen_rtx_PLUS (SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-+ dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-
- dst_mem_reg = reg;
- dst_mem = true;
-@@ -1322,13 +1398,13 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- if (base == addr)
- src = gen_rtx_MEM (mode, reg);
- else
-- src = gen_rtx_MEM (mode, gen_rtx_PLUS (SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-+ src = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-
- /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */
- if (src_op)
- {
- if (src_ee)
-- src = gen_rtx_fmt_ee (src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
-+ src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
- else
- {
- if (src_op == SIGN_EXTEND)
-@@ -1336,7 +1412,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- PUT_MODE_RAW(src, mode == SImode ? HImode : mode == HImode ? QImode : SImode);
- src->call = 1;
- }
-- src = gen_rtx_fmt_e (src_op, mode, src);
-+ src = gen_rtx_fmt_e(src_op, mode, src);
- }
- }
-
-@@ -1347,7 +1423,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- }
- }
-
-- pattern = gen_rtx_SET (dst, src);
-+ pattern = gen_rtx_SET(dst, src);
- src->volatil = vola;
-
- SET_INSN_DELETED(insn);
-@@ -2309,7 +2385,7 @@ opt_propagate_moves ()
-
- for (unsigned k = 0; k < jump_out.size (); ++k)
- {
-- rtx neu = gen_rtx_SET (
-+ rtx neu = gen_rtx_SET(
- dstj, gen_rtx_PLUS (Pmode, dsti, gen_rtx_CONST_INT (Pmode, fixups[k])));
- emit_insn_after (neu, jump_out[k]);
- }
-@@ -2386,7 +2462,7 @@ opt_strcpy ()
- int num_clobbers_to_add = 0;
- int insn_code_number;
-
-- rtx pattern = gen_rtx_SET (SET_DEST(single_set (reg2x)), SET_SRC(single_set (x2reg)));
-+ rtx pattern = gen_rtx_SET(SET_DEST(single_set (reg2x)), SET_SRC(single_set (x2reg)));
- rtx_insn * newinsn = make_insn_raw (pattern);
- insn_code_number = recog (PATTERN (newinsn), newinsn, &num_clobbers_to_add);
- if (insn_code_number >= 0 && check_asm_operands (PATTERN (newinsn)))
-@@ -2498,10 +2574,10 @@ opt_commute_add_move (void)
- if (!REG_P(memreg) || REGNO(memreg) != REGNO(reg1src))
- continue;
-
-- rtx pinc = gen_rtx_POST_INC (GET_MODE(dst), reg1dst);
-+ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1dst);
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
-- rtx_insn * newinsn = make_insn_raw (gen_rtx_SET (reg1dst, reg1src));
-+ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(reg1dst, reg1src));
- if (recog (PATTERN (newinsn), newinsn, 0) < 0 || !check_asm_operands (PATTERN (newinsn)))
- continue;
-
-@@ -2629,9 +2705,9 @@ opt_const_cmp_to_sub (void)
- {
- rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
- /* create the sub statement. */
-- rtx sub = gen_rtx_PLUS (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), intval));
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), intval));
-
-- rtx_insn * subinsn = make_insn_raw (gen_rtx_SET (copyreg, sub));
-+ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub));
-
- int num_clobbers_to_add = 0;
- int insn_code_number = recog (PATTERN (subinsn), subinsn, &num_clobbers_to_add);
-@@ -2648,8 +2724,8 @@ opt_const_cmp_to_sub (void)
- subinsn = emit_insn_before (PATTERN (subinsn), i1.get_insn ());
- i1.set_insn (subinsn);
-
-- rtx neu = gen_rtx_SET (cc0_rtx,
-- gen_rtx_COMPARE (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), 0)));
-+ rtx neu = gen_rtx_SET(cc0_rtx,
-+ gen_rtx_COMPARE (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), 0)));
-
- emit_insn_before (neu, i2.get_insn ());
-
-@@ -2670,8 +2746,8 @@ opt_const_cmp_to_sub (void)
- /* still a compare with 0 -> insert the sub. */
- rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
- /* create the sub statement. */
-- rtx sub = gen_rtx_PLUS (i1.get_mode (), copyreg, c);
-- rtx set = gen_rtx_SET (copyreg, sub);
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, c);
-+ rtx set = gen_rtx_SET(copyreg, sub);
- emit_insn_before (set, pp.get_insn ());
- }
- else
-@@ -2743,7 +2819,7 @@ opt_merge_add (void)
- rtx set = PATTERN (insn0);
-
- // convert lea (-1,a0),a1 into move.l a0,a1
-- rtx_insn * newins0 = make_insn_raw (gen_rtx_SET (XEXP(set, 0), XEXP(XEXP(set, 1), 0)));
-+ rtx_insn * newins0 = make_insn_raw (gen_rtx_SET(XEXP(set, 0), XEXP(XEXP(set, 1), 0)));
- add_insn_after (newins0, insn0, 0);
- SET_INSN_DELETED(insn0);
- // update infos accordingly
-@@ -3151,24 +3227,24 @@ opt_shrink_stack_frame (void)
- if (i < prologueend)
- {
- /* push */
-- rtx dec = gen_rtx_PRE_DEC (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
-+ rtx dec = gen_rtx_PRE_DEC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
-- rtx set = gen_rtx_SET (mem, reg);
-+ rtx set = gen_rtx_SET(mem, reg);
- emit_insn_after (set, insn);
- }
- else
- {
- /* pop */
-- rtx dec = gen_rtx_POST_INC (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
-+ rtx dec = gen_rtx_POST_INC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, a7);
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, dec);
-- rtx set = gen_rtx_SET (reg, mem);
-+ rtx set = gen_rtx_SET(reg, mem);
- emit_insn_before (set, insn);
- }
- }
- }
- else
- {
-- rtx parallel = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (regs.size () + add1 + clobbers.size ()));
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1 + clobbers.size ()));
- rtx plus;
-
- int x = 0;
-@@ -3179,8 +3255,8 @@ opt_shrink_stack_frame (void)
- /* no add if a5 is used with pop */
- if (add1)
- {
-- plus = gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-- XVECEXP(parallel, 0, l) = gen_rtx_SET (a7, plus);
-+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ? -x : x));
-+ XVECEXP(parallel, 0, l) = gen_rtx_SET(a7, plus);
- ++l;
- }
-
-@@ -3192,10 +3268,10 @@ opt_shrink_stack_frame (void)
- if (i < prologueend)
- {
- /* push */
-- plus = gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, -x));
-+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, -x));
- x -= REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-- rtx set = gen_rtx_SET (mem, regs[k]);
-+ rtx set = gen_rtx_SET(mem, regs[k]);
- XVECEXP(parallel, 0, l) = set;
- }
- else
-@@ -3204,17 +3280,17 @@ opt_shrink_stack_frame (void)
- if (usea5)
- {
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-- plus = gen_rtx_PLUS (SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
-+ plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-- rtx set = gen_rtx_SET (regs[k], mem);
-+ rtx set = gen_rtx_SET(regs[k], mem);
- XVECEXP(parallel, 0, l) = set;
- }
- else
- {
-- plus = x ? gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
-+ plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
- x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
- rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode, plus);
-- rtx set = gen_rtx_SET (regs[k], mem);
-+ rtx set = gen_rtx_SET(regs[k], mem);
- XVECEXP(parallel, 0, l) = set;
- }
- }
-@@ -3306,7 +3382,7 @@ opt_shrink_stack_frame (void)
- if (ii.in_proepi () >= IN_EPILOGUE && ii.get_sp_offset () != 0)
- {
- log ("(f) adjusting exit sp\n");
-- rtx pattern = gen_rtx_SET (
-+ rtx pattern = gen_rtx_SET(
- a7, gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, -ii.get_sp_offset ())));
- emit_insn_before (pattern, ii.get_insn ());
- }
-@@ -3325,7 +3401,7 @@ opt_shrink_stack_frame (void)
- rtx pattern = PATTERN (ii.get_insn ());
- unsigned sz = XVECLEN(pattern, 0);
-
-- rtx parallel = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (sz + 1));
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (sz + 1));
- unsigned n = 0;
- for (unsigned j = 0; j < sz; ++j)
- {
-@@ -3347,8 +3423,8 @@ opt_shrink_stack_frame (void)
-
- rtx a = copy_reg (a7, -1);
- a->frame_related = 1;
-- rtx plus = gen_rtx_PLUS (SImode, a, gen_rtx_CONST_INT (SImode, regs_total_size));
-- rtx set = gen_rtx_SET (a, plus);
-+ rtx plus = gen_rtx_PLUS(SImode, a, gen_rtx_CONST_INT (SImode, regs_total_size));
-+ rtx set = gen_rtx_SET(a, plus);
- XVECEXP(parallel, 0, 0) = set;
- SET_INSN_DELETED(ii.get_insn ());
- ii.set_insn (emit_insn_after (parallel, ii.get_insn ()));
-@@ -3766,14 +3842,14 @@ opt_absolute (void)
- if (with_symbol)
- {
- if (base)
-- lea = gen_rtx_SET (
-+ lea = gen_rtx_SET(
- gen_raw_REG (SImode, regno),
- gen_rtx_CONST (SImode, gen_rtx_PLUS (SImode, with_symbol, gen_rtx_CONST_INT (SImode, base))));
- else
-- lea = gen_rtx_SET (gen_raw_REG (SImode, regno), with_symbol);
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), with_symbol);
- }
- else
-- lea = gen_rtx_SET (gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
- rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
- insn_info nn (insn);
- nn.set_use (current_use);
-@@ -3800,6 +3876,158 @@ opt_absolute (void)
- return change_count;
- }
-
-+/*
-+ * Convert a series of reg with offset ( (ax), 4(ax), 8(ax), ...) into autoincx ( (ax+), (ax+), (ax+), ...)
-+ *
-+ * 1. search a mem(reg) without offset and either src or dst is using that reg
-+ * 2. follow paths until reg is dead
-+ * 3. if there is another mem(reg) with offset check that
-+ * a) offset fits last mode size
-+ * b) all remaining insn using that reg can be updated by
-+ * i) decrement the offset
-+ * ii) decrement the add value
-+ */
-+static unsigned
-+opt_autoinc ()
-+{
-+ unsigned change_count = 0;
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
++# Arrange for guides to be installed with GCC.
+
-+ if (ii.in_proepi ())
-+ continue;
++### begin-GG-local: gcc-amigaos
++#EXTRA_INSTALL_TARGETS = install-guide install-gcc-amigaos-doc
++### end-GG-local
+
-+ rtx reg = 0;
-+ if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 && !ii.get_src_mem_addr () && !ii.get_src_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-+ reg = ii.get_src_mem_reg ();
-+ if (!reg && ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-+ reg = ii.get_dst_mem_reg ();
-+ if (!reg)
-+ continue;
++# Where the guide files go
+
-+ int regno = REGNO(reg);
-+ int size = GET_MODE_SIZE(ii.get_mode ());
-+ if (size > 4)
-+ continue;
++guidedir = $(prefix)/guide
+
-+// log ("starting auto_inc search for %s at %d\n", reg_names[regno], index);
++# Actually install guides.
+
-+ // track all fixups to modify
-+ std::set<unsigned> fixups;
++installdirs-guide:
++ $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(guidedir)
+
-+ // all paths to check
-+ std::vector<unsigned> todo;
-+ todo.push_back (index + 1);
++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
+
-+ bool match_size = false;
-+ bool ok = true;
-+ std::set<unsigned> visited;
-+ while (ok && todo.size () > 0)
-+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
++$(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
+
-+ if (pos == index)
-+ {
-+ ok = false;
-+ break;
-+ }
++### begin-GG-local: gcc-amigaos
++# Build and install gcc-amigaos.guide - documentation specific to the
++# AmigaOS port of GCC.
+
-+ if (visited.find (pos) != visited.end ())
-+ continue;
-+ visited.insert (pos);
++gcc-amigaos-doc:: doc/gcc-amigaos.info doc/gcc-amigaos.guide
+
-+ for (; pos < infos.size (); ++pos)
-+ {
-+ insn_info & jj = infos[pos];
++doc/gcc-amigaos.info doc/gcc-amigaos.guide: gcc-amigaos.texi
+
-+ // run over labels
-+ if (jj.is_label ())
-+ continue;
++install-gcc-amigaos-doc: doc installdirs installdirs-guide \
++ $(DESTDIR)$(infodir)/gcc-amigaos.info \
++ $(DESTDIR)$(guidedir)/gcc-amigaos.guide
++### end-GG-local
+
-+ // break if no longer user
-+ if (!jj.is_use (regno))
-+ break;
++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/gcc/config/m68k/xm-amigaos.h b/gcc/config/m68k/xm-amigaos.h
+new file mode 100755
+index 000000000000..bb571ba040b3
+--- /dev/null
++++ gcc/config/m68k/xm-amigaos.h
+@@ -0,0 +1,64 @@
++/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
++ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
++ Free Software Foundation, Inc.
++ Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch).
+
-+ if (jj.in_proepi ())
-+ {
-+ ok = false;
-+ break;
-+ }
++This file is part of GCC.
+
-+ // break if in epilogue or add all labels
-+ if (jj.is_jump ())
-+ {
-+ for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end () && j->first == k->first;
-+ ++j)
-+ todo.push_back (j->second);
-+ continue;
-+ }
++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.
+
-+ // not used directly
-+ if (!jj.is_myuse (regno))
-+ continue;
++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.
+
-+ // if reg is src reg, op must be add and addend must be large enough
-+ if (jj.get_src_regno () == regno || jj.get_src_mem_regno () == regno)
-+ {
-+ if (jj.get_src_intval () < size || (jj.get_dst_mem_regno () == regno && jj.get_dst_addr () < size))
-+ {
-+ ok = false;
-+ break;
-+ }
++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. */
+
-+ if (jj.get_dst_addr () == size)
-+ match_size = true;
++#ifndef _FCNTL_H_
++#include <fcntl.h>
++#endif
+
-+ fixups.insert (pos);
-+ // end chain, if self assign
-+ if (jj.get_dst_regno () == regno)
-+ break;
++/* 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. */
+
-+ continue;
-+ }
++#define SYSTEM_INCLUDE_DIR "/gg/os-include"
++#define STANDARD_INCLUDE_DIR "/gg/include"
+
-+ if (jj.get_dst_mem_regno () == regno)
-+ {
-+ if (jj.get_dst_addr () < size)
-+ {
-+ ok = false;
-+ break;
-+ }
-+ if (jj.get_dst_addr () == size)
-+ match_size = true;
-+ fixups.insert (pos);
-+ }
-+ }
-+ }
++#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/"
+
-+ if (!ok || !match_size || !fixups.size ())
-+ continue;
++/* The AmigaOS stores file names with regard to upper/lower case, but actions
++ on existing files are case independent on the standard filesystems.
+
-+ log ("(i) auto_inc for %s at %d\n", reg_names[regno], index);
++ 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.
+
-+ ii.make_post_inc (regno);
++ 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. */
+
-+ // fix all offsets / adds
-+ for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
-+ {
-+// log ("(i) fixup at %d\n", *k);
++#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE))
+
-+ insn_info & kk = infos[*k];
++/* 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. */
+
-+ kk.auto_inc_fixup (regno, size);
-+ }
-+ ++change_count;
-+ --index; // rerun insn to check src and dst
-+ }
++#define DIR_SEPARATOR '/'
++#define VOL_SEPARATOR ':'
++#define DIR_SEPARATOR_2 VOL_SEPARATOR
+
-+ return change_count;
-+}
++/* Zap PREFIX_INCLUDE_DIR, since with the AmigaOS port it is the same as
++ STANDARD_INCLUDE_DIR. */
+
- namespace
- {
++#undef PREFIX_INCLUDE_DIR
+diff --git a/gcc/coretypes.h b/gcc/coretypes.h
+index 12067fdf5348..f0f069f6afa2 100644
+--- gcc/coretypes.h
++++ gcc/coretypes.h
+@@ -52,9 +52,9 @@ typedef const struct bitmap_head *const_bitmap;
+ struct simple_bitmap_def;
+ typedef struct simple_bitmap_def *sbitmap;
+ typedef const struct simple_bitmap_def *const_sbitmap;
+-struct rtx_def;
+-typedef struct rtx_def *rtx;
+-typedef const struct rtx_def *const_rtx;
++class rtx_def;
++typedef class rtx_def *rtx;
++typedef const class rtx_def *const_rtx;
-@@ -3870,6 +4098,7 @@ namespace
- bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
- bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
- bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
-+ bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
+ /* Subclasses of rtx_def, using indentation to show the class
+ hierarchy, along with the relevant invariant.
+diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
+index 03cbde090cb3..83a5ab514c79 100644
+--- gcc/cp/g++spec.c
++++ gcc/cp/g++spec.c
+@@ -262,7 +262,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ #endif
- if (be_very_verbose)
- log ("ENTER\n");
-@@ -3901,6 +4130,9 @@ namespace
- if (do_elim_dead_assign && opt_elim_dead_assign ())
- done = 0, update_insns ();
+ /* Add one for shared_libgcc or extra static library. */
+- num_args = argc + added + need_math + (library > 0) * 4 + 1;
++ num_args = argc + added + need_math + (library > 0) * 5 + 1;
+ new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
-+ if (do_autoinc && opt_autoinc ())
-+ done = 0, update_insns ();
+ i = 0;
+@@ -347,6 +347,30 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ CL_DRIVER, &new_decoded_options[j]);
+ added_libraries++;
+ j++;
+
- if (do_bb_reg_rename)
- {
- while (opt_reg_rename ())
-
-From 210ee63e6fd9926deb41a28130f5c1b5e1dde8ba Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 14 Jun 2017 23:40:23 +0200
-Subject: [PATCH 177/303] @B handle compare correctly if converting to autoinc
-
----
- gcc/bbb-opts.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 23d8fdb582c3..b81c4db7f136 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -825,13 +825,18 @@ insn_info::make_post_inc (int regno)
- {
- // convert into POST_INC
- // debug_rtx (insn);
-- rtx set = single_set (insn);
-+ rtx set0 = single_set (insn);
-+ rtx set = set0;
-+ SET_INSN_DELETED(insn);
-+ if (is_compare ())
-+ set = SET_SRC(set);
- rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
- rtx reg = XEXP(mem, 0);
- XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
--// debug_rtx (insn);
-
- (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
-+ insn = emit_insn_after(set0, insn);
-+// debug_rtx (insn);
- }
-
- void
-@@ -839,8 +844,9 @@ insn_info::auto_inc_fixup (int regno, int size)
- {
- // debug_rtx (insn);
-
-- rtx set = single_set (insn);
--
-+ rtx set0 = single_set (insn);
-+ rtx set = set0;
-+ SET_INSN_DELETED(insn);
- if (is_compare ())
- set = SET_SRC(set);
-
-@@ -875,6 +881,7 @@ insn_info::auto_inc_fixup (int regno, int size)
- XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)),
- (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) -= size);
- }
-+ insn = emit_insn_after(set0, insn);
- // debug_rtx (insn);
- }
-
-
-From 9253b9cbb4784817cc6a112b4cb672b721ee131e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 16 Jun 2017 13:05:58 +0200
-Subject: [PATCH 178/303] @B mark word/byte defs as use
-
----
- gcc/bbb-opts.c | 35 +++++++++++++++++------------------
- 1 file changed, 17 insertions(+), 18 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index b81c4db7f136..1a5468418601 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -835,7 +835,7 @@ insn_info::make_post_inc (int regno)
- XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
-
- (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
-- insn = emit_insn_after(set0, insn);
-+ insn = emit_insn_after (set0, insn);
- // debug_rtx (insn);
- }
-
-@@ -881,7 +881,7 @@ insn_info::auto_inc_fixup (int regno, int size)
- XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)),
- (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) -= size);
- }
-- insn = emit_insn_after(set0, insn);
-+ insn = emit_insn_after (set0, insn);
- // debug_rtx (insn);
- }
-
-@@ -1678,14 +1678,14 @@ update_insn_infos (void)
- NOTICE_UPDATE_CC(PATTERN (insn), insn);
- if (cc_status.value1 || cc_status.value2)
- use.mark_def (FIRST_PSEUDO_REGISTER);
--
-- // also check mode size if < 4, it's also a def.
-- if (ii.get_dst_reg () && GET_MODE_SIZE(ii.get_mode()) < 4)
-- use.mark_def (ii.get_dst_regno ());
- }
-
-+ // also check mode size if < 4, it's also a use.
-+ if (pp.get_dst_reg () && GET_MODE_SIZE(pp.get_mode()) < 4)
-+ use.mark_use (pp.get_dst_regno ());
++#ifdef TARGET_AMIGA
++ {
++ bool addglue = true;
++ /* do not add glue if exceptions are disabled. */
++ for (int ii = 0; ii < argc; ++ii)
++ {
++ if (decoded_options[ii].opt_index == OPT_fexceptions)
++ addglue = decoded_options[ii].value;
++ }
++ if (addglue)
++ {
++ extern const char *
++ amiga_m68k_prefix_func (int argc, const char ** argv);
++ char const * cxxglue = "../lib/gcc/m68k-amigaos/"
++ DEFAULT_TARGET_VERSION
++ "/cxxglue.o";
++ char const * p = amiga_m68k_prefix_func (1, &cxxglue);
++ generate_option_input_file (p, &new_decoded_options[j]);
++ ++j;
++ }
++ }
++#endif
+
- /* mark not renameable in prologue/epilogue. */
-- if (infos[pos].in_proepi () != IN_CODE)
-+ if (pp.in_proepi () != IN_CODE)
- use.make_hard ();
-
- ii.merge (use);
-@@ -3955,7 +3955,7 @@ opt_autoinc ()
- if (jj.is_label ())
- continue;
-
-- // break if no longer user
-+ // break if no longer used
- if (!jj.is_use (regno))
- break;
-
-@@ -3965,7 +3965,7 @@ opt_autoinc ()
- break;
- }
-
-- // break if in epilogue or add all labels
-+ // add all labels
- if (jj.is_jump ())
- {
- for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end () && j->first == k->first;
-@@ -3991,24 +3991,24 @@ opt_autoinc ()
- match_size = true;
-
- fixups.insert (pos);
-- // end chain, if self assign
-- if (jj.get_dst_regno () == regno)
-- break;
--
-- continue;
- }
--
-- if (jj.get_dst_mem_regno () == regno)
-+ else if (jj.get_dst_mem_regno () == regno)
- {
- if (jj.get_dst_addr () < size)
- {
- ok = false;
- break;
- }
-+
- if (jj.get_dst_addr () == size)
- match_size = true;
-+
- fixups.insert (pos);
- }
-+
-+ // done if this is an add
-+ if (ii.is_def (regno))
-+ break;
- }
- }
-
-@@ -4023,11 +4023,10 @@ opt_autoinc ()
- for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
+ /* Add target-dependent static library, if necessary. */
+ if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
{
- // log ("(i) fixup at %d\n", *k);
--
- insn_info & kk = infos[*k];
--
- kk.auto_inc_fixup (regno, size);
- }
+diff --git a/gcc/df-scan.c b/gcc/df-scan.c
+index 98de84405428..1f23452afe19 100644
+--- gcc/df-scan.c
++++ gcc/df-scan.c
+@@ -1807,6 +1807,12 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
+ df_ref *ref_ptr;
+ struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref);
+
++ if (DF_REF_FLAGS_IS_SET(the_ref, DF_HARD_REG_LIVE))
++ {
++ --df->hard_regs_live_count[DF_REF_REGNO(the_ref)];
++ ++df->hard_regs_live_count[new_regno];
++ }
+
- ++change_count;
- --index; // rerun insn to check src and dst
- }
-
-From f0beccad3618cddcc3744347b5e000251394e1f4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 16 Jun 2017 21:12:11 +0200
-Subject: [PATCH 179/303] @B reg rename backward start search must not run over
- unconditional jumps
-
----
- gcc/bbb-opts.c | 89 ++++++++++++++++++++++++++++++++++++----------------------
- 1 file changed, 55 insertions(+), 34 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 1a5468418601..f60232116968 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -71,6 +71,8 @@
- #include <set>
- #include <map>
+ DF_REF_REGNO (the_ref) = new_regno;
+ DF_REF_REG (the_ref) = regno_reg_rtx[new_regno];
-+static int xx = 0;
+diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
+index f241073866b4..566aaaf4e370 100644
+--- gcc/dwarf2out.c
++++ gcc/dwarf2out.c
+@@ -451,7 +451,7 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
+ /*global=*/1);
+ lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,
+ /*global=*/0);
+- flags = ((! flag_pic
++ flags = (( (!flag_pic || flag_pic > 2)
+ || ((fde_encoding & 0x70) != DW_EH_PE_absptr
+ && (fde_encoding & 0x70) != DW_EH_PE_aligned
+ && (per_encoding & 0x70) != DW_EH_PE_absptr
+@@ -469,6 +469,16 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
+ eh_frame_section = ((flags == SECTION_WRITE)
+ ? data_section : readonly_data_section);
+ #endif /* EH_FRAME_SECTION_NAME */
++
++#ifdef TARGET_AMIGA
++ switch_to_section (data_section);
++ fputs("\t__EH_FRAME_OBJECT__:\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long 0\n", asm_out_file);
++ fputs("\t.stabs \"__EH_FRAME_OBJECTS__\",24,0,0,__EH_FRAME_OBJECT__\n", asm_out_file);
+
- bool be_very_verbose;
- bool be_verbose;
++ switch_to_section (eh_frame_section);
++ ASM_OUTPUT_LABEL (asm_out_file, "_EH_FRAME_BEGIN__");
++ fputs("\t.stabs \"__EH_FRAME_BEGINS__\",22,0,0,__EH_FRAME_BEGIN__\n", asm_out_file);
++#endif
+ }
-@@ -1487,7 +1489,7 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- insn_info & ii = *i->second;
+ switch_to_section (eh_frame_section);
+diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
+index 0fcd9d95e5b4..b2a18e7e4188 100644
+--- gcc/emit-rtl.c
++++ gcc/emit-rtl.c
+@@ -2123,7 +2123,11 @@ change_address_1 (rtx memref, machine_mode mode, rtx addr, int validate,
+ if (validate && !lra_in_progress)
+ {
+ if (reload_in_progress || reload_completed)
+- gcc_assert (memory_address_addr_space_p (mode, addr, as));
++ {
++ bool r = memory_address_addr_space_p (mode, addr, as);
++ if (!r) debug_rtx(addr);
++ gcc_assert (r);
++ }
+ else
+ addr = memory_address_addr_space (mode, addr, as);
+ }
+diff --git a/gcc/except.c b/gcc/except.c
+index 2a1073f80cc4..194478f8454c 100644
+--- gcc/except.c
++++ gcc/except.c
+@@ -142,6 +142,7 @@ along with GCC; see the file COPYING3. If not see
+ #include "cfgloop.h"
+ #include "builtins.h"
+ #include "tree-hash-traits.h"
++#include "target-def.h"
- if (f != stderr)
-- fprintf (f, "\n\t\t\t\t\t\t|");
-+ fprintf (f, "\n\t\t\t\t\t|%d\t", ii.get_index ());
+ static GTY(()) int call_site_base;
- fprintf (f, "%c ",
- ii.is_stack () ? 's' : ii.in_proepi () == IN_PROLOGUE ? 'p' : ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
-@@ -1680,9 +1682,10 @@ update_insn_infos (void)
- use.mark_def (FIRST_PSEUDO_REGISTER);
+@@ -2850,14 +2851,14 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
+ it linkonce if we have COMDAT groups to tie them together. */
+ if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)
+ flags |= SECTION_LINKONCE;
+- sprintf (section_name, ".gcc_except_table.%s", fnname);
++ sprintf (section_name, TARGET_GCC_EXCEPT_TABLE_S, fnname);
+ s = get_section (section_name, flags, current_function_decl);
+ free (section_name);
}
+ else
+ #endif
+ exception_section
+- = s = get_section (".gcc_except_table", flags, NULL);
++ = s = get_section (TARGET_GCC_EXCEPT_TABLE, flags, NULL);
+ }
+ else
+ exception_section
+diff --git a/gcc/final.c b/gcc/final.c
+index 55cf509611f7..fa8b2964a40d 100644
+--- gcc/final.c
++++ gcc/final.c
+@@ -2151,6 +2151,7 @@ call_from_call_insn (rtx_call_insn *insn)
+ SEEN is used to track the end of the prologue, for emitting
+ debug information. We force the emission of a line note after
+ both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */
++rtx_insn * current_insn;
-- // also check mode size if < 4, it's also a use.
-- if (pp.get_dst_reg () && GET_MODE_SIZE(pp.get_mode()) < 4)
-- use.mark_use (pp.get_dst_regno ());
-+ // TODO: use 2 bits for data regs, to indicate mode size
-+// // also check mode size if < 4, it's also a use for data registers.
-+// if (pp.get_dst_reg () && pp.get_dst_regno () < 8 && GET_MODE_SIZE(pp.get_mode()) < 4)
-+// use.mark_use (pp.get_dst_regno ());
-
- /* mark not renameable in prologue/epilogue. */
- if (pp.in_proepi () != IN_CODE)
-@@ -1908,12 +1911,17 @@ find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
- {
- unsigned startm1 = start - 1;
+ rtx_insn *
+ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
+@@ -2160,6 +2161,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
+ rtx set;
+ #endif
+ rtx_insn *next;
++ current_insn = insn;
-- /* already searched. */
-- if (found.find (startm1) != found.end ())
-- break;
-+// /* already searched. */
-+// if (found.find (startm1) != found.end ())
-+// break;
+ insn_counter++;
- /* do not run over RETURNS */
- insn_info & jj = infos[start];
-+
-+ /* stop at labels. If a label is a start pos, a search is maybe started again. */
-+ if (jj.is_label ())
-+ break;
-+
- insn_info & bb = infos[startm1];
- if (jj.in_proepi () == IN_CODE && bb.in_proepi () >= IN_EPILOGUE)
- break;
-@@ -1933,6 +1941,7 @@ find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
- static unsigned
- opt_reg_rename (void)
+@@ -3622,6 +3624,12 @@ do_assembler_dialects (const char *p, int *dialect)
+ void
+ output_asm_insn (const char *templ, rtx *operands)
{
-+ update_label2jump ();
- // dump_insns ("rename", 1);
- for (unsigned index = 0; index < infos.size (); ++index)
- {
-@@ -1988,15 +1997,38 @@ opt_reg_rename (void)
- {
- i2i_iterator j = insn2info.find (i->second);
- if (j == insn2info.end ())
-- continue;
-+ {
-+ mask = 0;
-+ break;
-+ }
-
- unsigned start = j->second->get_index ();
-- if (!infos[start].is_use (rename_regno))
-+ if (found.find (start) != found.end () || !infos[start].is_use (rename_regno))
- continue;
-
-+// printf ("label %d <- %d jump\n", pos, start); fflush (stdout);
-+
- start = find_start (found, start, rename_regno);
- todo.insert (start);
- }
-+
-+ /* if this label is at a start, check if it is reachable from the previous insn,
-+ * and if, check for use then search start. */
-+ if (pos == runpos && pos > 0)
-+ {
-+ insn_info & bb = infos[pos - 1];
-+ rtx set = single_set (bb.get_insn ());
-+ if (ANY_RETURN_P(bb.get_insn ())
-+ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) != IF_THEN_ELSE))
-+ continue;
++ extern bool be_very_verbose;
++ extern void append_reg_usage(FILE *, rtx_insn *);
+
-+ if (bb.is_use (rename_regno))
-+ {
-+ unsigned start = find_start (found, pos - 1, rename_regno);
-+ todo.insert (start);
-+ }
-+ }
++ extern bool dump_reg_track;
++ void append_reg_cache (FILE * f, rtx_insn * insn);
+
- continue;
- }
-
-@@ -2035,37 +2067,21 @@ opt_reg_rename (void)
- /* follow jump and/or next insn. */
- if (JUMP_P(insn))
- {
-- i2i_iterator j = insn2info.find ((rtx_insn *) JUMP_LABEL(insn));
-- if (j == insn2info.end ())
-+ for (j2l_iterator i = jump2label.find (pos), k = i; i != jump2label.end () && i->first == k->first;
-+ ++i)
- {
-- /* whoops - label not found. */
-- mask = 0;
-- break;
-- }
-+ unsigned label_index = i->second;
-
-- unsigned label_index = j->second->get_index ();
-- if (found.find (label_index) == found.end ())
-- {
-- /* if the rename_reg is used in the insn before.
-- * search the start.
-- */
-+ /* add the label to the search list. */
- insn_info & bb = infos[label_index + 1];
-- if (bb.is_use (rename_regno))
-+ if (found.find (label_index) == found.end () && bb.is_use (rename_regno))
- {
-- unsigned start = find_start (found, label_index, rename_regno);
-- todo.insert (start);
-+// printf ("jump %d -> %d label\n", pos, label_index); fflush (stdout);
-+ todo.insert (label_index);
- }
-- todo.insert (label_index + 1);
-- }
-- rtx jmppattern = PATTERN (insn);
-- if (GET_CODE(jmppattern) == PARALLEL)
-- {
-- /* can't handle yet. Abort renaming. */
-- mask = 0;
-- break;
- }
--
-- rtx jmpsrc = XEXP(jmppattern, 1);
-+ rtx set = single_set (insn);
-+ rtx jmpsrc = SET_SRC(set);
- if (!jmpsrc || GET_CODE(jmpsrc) != IF_THEN_ELSE)
- break;
- }
-@@ -4106,6 +4122,11 @@ namespace
- bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
- bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
+ const char *p;
+ int c;
+ #ifdef ASSEMBLER_DIALECT
+@@ -3778,6 +3786,11 @@ output_asm_insn (const char *templ, rtx *operands)
+ putc (c, asm_out_file);
+ }
-+ ++xx;
-+ printf ("x: %d\n", xx);
-+// if (xx <= 90 || xx > 93)
-+// do_bb_reg_rename = false;
++ if (be_very_verbose)
++ append_reg_usage(asm_out_file, current_insn);
++ if (dump_reg_track)
++ append_reg_cache(asm_out_file, current_insn);
+
- if (be_very_verbose)
- log ("ENTER\n");
+ /* Write out the variable names for operands, if we know them. */
+ if (flag_verbose_asm)
+ output_asm_operand_names (operands, oporder, ops);
+@@ -3995,6 +4008,7 @@ output_addr_const (FILE *file, rtx x)
+ if (targetm.asm_out.output_addr_const_extra (file, x))
+ break;
-
-From 77e758b888024c9df2267f0e344ff46efa763951 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 16 Jun 2017 21:53:51 +0200
-Subject: [PATCH 180/303] @B update jump2label lookup for autoincs
-
----
- gcc/bbb-opts.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f60232116968..473dba829926 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3914,6 +3914,9 @@ static unsigned
- opt_autoinc ()
- {
- unsigned change_count = 0;
-+
-+ update_label2jump();
++ debug_rtx(current_output_insn);
+ output_operand_lossage ("invalid expression as operand");
+ }
+ }
+diff --git a/gcc/function.c b/gcc/function.c
+index 6942a504127f..ebe3e1c37121 100644
+--- gcc/function.c
++++ gcc/function.c
+@@ -39,9 +39,9 @@ along with GCC; see the file COPYING3. If not see
+ #include "rtl.h"
+ #include "tree.h"
+ #include "gimple-expr.h"
++#include "tm_p.h"
+ #include "cfghooks.h"
+ #include "df.h"
+-#include "tm_p.h"
+ #include "stringpool.h"
+ #include "expmed.h"
+ #include "optabs.h"
+diff --git a/gcc/gcc.c b/gcc/gcc.c
+index 85ea19bd3a09..a4da7d515ce5 100644
+--- gcc/gcc.c
++++ gcc/gcc.c
+@@ -10107,3 +10107,40 @@ driver_get_configure_time_options (void (*cb) (const char *option,
+ obstack_free (&obstack, NULL);
+ n_switches = 0;
+ }
+
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-@@ -4122,10 +4125,10 @@ namespace
- bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
- bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
-
-- ++xx;
-- printf ("x: %d\n", xx);
--// if (xx <= 90 || xx > 93)
--// do_bb_reg_rename = false;
-+// ++xx;
-+// printf ("x: %d\n", xx);
-+// if (xx <= 86 || xx > 90)
-+// do_autoinc = false;
-
- if (be_very_verbose)
- log ("ENTER\n");
-
-From 669a03b0c64ae38eb9e231cabad983fd6e583325 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 16 Jun 2017 22:26:00 +0200
-Subject: [PATCH 181/303] @B cancel autoinc attempt if reg is directly used
-
----
- gcc/bbb-opts.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 473dba829926..85f1efea09ab 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3915,7 +3915,7 @@ opt_autoinc ()
- {
- unsigned change_count = 0;
-
-- update_label2jump();
-+ update_label2jump ();
-
- for (unsigned index = 0; index < infos.size (); ++index)
- {
-@@ -4024,6 +4024,11 @@ opt_autoinc ()
-
- fixups.insert (pos);
- }
-+ else
++#ifdef TARGET_AMIGA
++const char * amiga_m68k_prefix_func(int argc, const char ** argv) {
++ char * p = 0;
++ if (standard_libexec_prefix)
++ {
++ char * glp = concat(standard_libexec_prefix, "", NULL);
++ p = strrchr(glp, '/');
++ if (p)
++ {
++ *p = 0;
++ p = strrchr(glp, '/');
++ if (p)
++ {
++ *p = 0;
++ p = strrchr(glp, '/');
++ if (p)
+ {
-+ ok = false;
-+ break;
++ p[1] = 0;
++ p = concat(glp, "m68k-amigaos/", NULL);
+ }
++ }
++ }
++ free(glp);
++ }
++ if (!p)
++ p = concat("../../../../", "", NULL);
++
++ for (int i = 0; i < argc; ++i) {
++ char * q = concat(p, argv[i], NULL);
++ free(p);
++ p = q;
++ }
++// printf("amiga_m68k_prefix_func='%s'\n", p);
++ return p;
++}
++#endif
+diff --git a/gcc/gcse.c b/gcc/gcse.c
+index 5b2c96ecb5a6..f74e733f9337 100644
+--- gcc/gcse.c
++++ gcc/gcse.c
+@@ -4075,7 +4075,9 @@ pass_rtl_pre::gate (function *fun)
+ {
+ return optimize > 0 && flag_gcse
+ && !fun->calls_setjmp
++#ifndef TARGET_AMIGA
+ && optimize_function_for_speed_p (fun)
++#endif
+ && dbg_cnt (pre);
+ }
- // done if this is an add
- if (ii.is_def (regno))
-@@ -4127,7 +4132,7 @@ namespace
-
- // ++xx;
- // printf ("x: %d\n", xx);
--// if (xx <= 86 || xx > 90)
-+// if (xx <= 48 || xx > 54)
- // do_autoinc = false;
-
- if (be_very_verbose)
-
-From 206ae2727760bc76ca01b111f470b1ed70beced8 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 17 Jun 2017 16:11:36 +0200
-Subject: [PATCH 182/303] @B autoinc is now checking the jumps to a label for
- register usage
-
----
- gcc/bbb-opts.c | 18 ++++++++++++++++--
- 1 file changed, 16 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 85f1efea09ab..db791406b0fb 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3970,9 +3970,23 @@ opt_autoinc ()
- {
- insn_info & jj = infos[pos];
-
-- // run over labels
-+ // check all jumps labels for register usage
- if (jj.is_label ())
-- continue;
-+ {
-+ for (l2j_iterator j = label2jump.find (jj.get_insn ()->u2.insn_uid), k = j;
-+ j != label2jump.end () && j->first == k->first; ++j)
-+ {
-+ insn_info * ll = insn2info.find (j->second)->second;
-+ if (ll->is_use (regno))
-+ {
-+ ok = false;
-+ break;
-+ }
-+ }
-+ if (ok)
-+ continue;
-+ break;
-+ }
+@@ -4118,6 +4120,9 @@ class pass_rtl_hoist : public rtl_opt_pass
+ bool
+ pass_rtl_hoist::gate (function *)
+ {
++#ifdef TARGET_AMIGA
++ return false;
++#else
+ return optimize > 0 && flag_gcse
+ && !cfun->calls_setjmp
+ /* It does not make sense to run code hoisting unless we are optimizing
+@@ -4125,6 +4130,7 @@ pass_rtl_hoist::gate (function *)
+ bigger if we did PRE (when optimizing for space, we don't run PRE). */
+ && optimize_function_for_size_p (cfun)
+ && dbg_cnt (hoist);
++#endif
+ }
- // break if no longer used
- if (!jj.is_use (regno))
-
-From bc3028a6f267699e0d6556b310a5cb75c2600e22 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 17 Jun 2017 21:44:32 +0200
-Subject: [PATCH 183/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index bbab26fe7028..e3b60659878c 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170613-160057
-+20170617-214407
-
-From 98d760a8b0e4aaeccd8a37d6a55d425853628b1a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 18 Jun 2017 13:09:59 +0200
-Subject: [PATCH 184/303] @B fix for some jump insns with parallel rtx (dbcc)
-
----
- gcc/bbb-opts.c | 16 +++++++++++++++-
- 1 file changed, 15 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index db791406b0fb..f66256954f17 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2081,7 +2081,21 @@ opt_reg_rename (void)
- }
- }
- rtx set = single_set (insn);
-- rtx jmpsrc = SET_SRC(set);
-+ if (!set)
-+ {
-+ // it's a parallel pattern - search the set pc = ...
-+ rtx pat = PATTERN (insn);
-+ for (int j = XVECLEN (pat, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pat, 0, j);
-+ if (XEXP(x, 0) == pc_rtx)
-+ {
-+ set = x;
-+ break;
-+ }
-+ }
-+ }
-+ rtx jmpsrc = set ? SET_SRC(set) : 0;
- if (!jmpsrc || GET_CODE(jmpsrc) != IF_THEN_ELSE)
- break;
- }
-
-From 8bfc9663a96e6256cd360ab4355c8b66515f13f1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 18 Jun 2017 13:11:04 +0200
-Subject: [PATCH 185/303] @R define _WCHAR_T_ if typedef-ing wchar_t
-
----
- gcc/ginclude/stddef.h | 1 +
- 1 file changed, 1 insertion(+)
-
+ } // anon namespace
diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
index d711530d0535..4f08f81a3ae0 100644
--- gcc/ginclude/stddef.h
@@ -33517,856 +9954,448 @@ index d711530d0535..4f08f81a3ae0 100644
typedef __WCHAR_TYPE__ wchar_t;
#endif
#endif
-
-From 3362e147aee470ae0715005e851264a30634aefc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 18 Jun 2017 13:11:43 +0200
-Subject: [PATCH 186/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index e3b60659878c..668d20875bcc 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170617-214407
-+20170618-131118
-
-From c57b23b7b2ac0771437f22e7e9ca81ddbe0f04fa Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 20 Jun 2017 19:12:21 +0200
-Subject: [PATCH 187/303] @B fix autoinc generation if src op is present
-
----
- gcc/bbb-opts.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f66256954f17..074669a4e844 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -833,6 +833,9 @@ insn_info::make_post_inc (int regno)
- if (is_compare ())
- set = SET_SRC(set);
- rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-+ if (src_op && get_src_mem_regno () == regno)
-+ mem = XEXP(mem, 1);
-+
- rtx reg = XEXP(mem, 0);
- XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
-
-
-From 85a73d1de786d310f2c9b8fad247f82c1c233e33 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 20 Jun 2017 19:13:37 +0200
-Subject: [PATCH 188/303] @V bump version
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 668d20875bcc..2c8dad4e8bed 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170618-131118
-+20170620-191317
-
-From 8adf18dc9ae9c93578612b11935146fc572b662e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 21 Jun 2017 13:34:32 +0200
-Subject: [PATCH 189/303] @B fix flow analysis with tail calls converted to
- jumps
-
----
- gcc/bbb-opts.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 074669a4e844..f9e6e4008a44 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1829,12 +1829,15 @@ update_insns ()
- jump_table = 0;
- ii.set_proepi (inproepilogue = IN_CODE);
- if (infos.size () > 1)
-- scan_starts.insert (infos.size () - 1);
-+ scan_starts.insert (infos.size () - 2);
- }
- else if (CALL_P(insn))
- {
-- if (insn->jump)
-+ if (insn->jump) {
- ii.set_proepi (IN_EPILOGUE);
-+ ii.mark_jump();
-+ scan_starts.insert (infos.size () - 1);
-+ }
- ii.mark_call ();
- if (inproepilogue)
- {
-
-From ad1cbe3452a5355dde8947bc91c41145d56c19c2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 21 Jun 2017 13:35:44 +0200
-Subject: [PATCH 190/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 2c8dad4e8bed..e907b4926b96 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170620-191317
-+20170621-133511
-
-From c1fff35716644f7270e12a819bad64a328ce530b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 21 Jun 2017 19:32:08 +0200
-Subject: [PATCH 191/303] @B do not eliminate self updates, e.g. (a0),a0
-
----
- gcc/bbb-opts.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f9e6e4008a44..352c14d18c6c 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3716,7 +3716,7 @@ opt_elim_dead_assign (void)
- ++change_count;
- continue;
- }
-- if (ii.get_src_op () == 0 && ii.get_dst_reg ())
-+ if (ii.get_src_op () == 0 && ii.get_dst_reg () && !ii.is_use(ii.get_dst_regno()))
- {
- rtx cached_value = ii.get_track_var ()->get_values ()[ii.get_dst_regno ()];
- rtx cached_value2 = 0;
-
-From f573652f798f9ea72796cced3b8044d3dafd7bad Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 22 Jun 2017 15:20:24 +0200
-Subject: [PATCH 192/303] @B fix flow analysis, @D V dumps now no index
- numbers, vV dumps index numbers into asm
-
----
- gcc/bbb-opts.c | 51 +++++++++++++++++++++++++++++++++++----------------
- 1 file changed, 35 insertions(+), 16 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 352c14d18c6c..8b49637f6c09 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -73,7 +73,7 @@
-
- static int xx = 0;
-
--bool be_very_verbose;
-+int be_very_verbose;
- bool be_verbose;
-
- extern struct lang_hooks lang_hooks;
-@@ -1468,13 +1468,13 @@ is_reg_dead (unsigned regno, unsigned _pos)
- // skip labels.
- for (unsigned pos = _pos + 1; pos < infos.size (); ++pos)
- {
-- insn_info & ii0 = infos[pos];
-+ insn_info & ii = infos[pos];
- // skip entries without info
-- if (ii0.is_empty ())
-+ if (ii.is_empty ())
- continue;
+diff --git a/gcc/hwint.h b/gcc/hwint.h
+index 4dd255d486c5..d5296a81d08e 100644
+--- gcc/hwint.h
++++ gcc/hwint.h
+@@ -295,7 +295,7 @@ abs_hwi (HOST_WIDE_INT x)
+ inline unsigned HOST_WIDE_INT
+ absu_hwi (HOST_WIDE_INT x)
+ {
+- return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x;
++ return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(signed HOST_WIDE_INT)x;
+ }
- // not dead if usage is reported in the next statement
-- return !ii0.is_use (regno) && !ii0.is_hard (regno);
-+ return !ii.is_use (regno) && !ii.is_hard (regno);
- }
- return true;
+ #endif /* ! GCC_HWINT_H */
+diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
+index 86c48f14f64d..dc72a5f21021 100644
+--- gcc/ipa-chkp.c
++++ gcc/ipa-chkp.c
+@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see
+ #include "system.h"
+ #include "coretypes.h"
+ #include "backend.h"
++#include "tm_p.h"
++#include "target.h"
+ #include "tree.h"
+ #include "gimple.h"
+ #include "tree-pass.h"
+diff --git a/gcc/opts.c b/gcc/opts.c
+index 8f9862db57c2..6a87349e6a70 100644
+--- gcc/opts.c
++++ gcc/opts.c
+@@ -530,8 +530,10 @@ static const struct default_options default_options_table[] =
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
+ { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
+ { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
++#ifndef TARGET_AMIGA
+ { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
+ { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
++#endif
+ { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
+ { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
+ { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
+diff --git a/gcc/passes.c b/gcc/passes.c
+index e89618111245..1d53bb23b1b0 100644
+--- gcc/passes.c
++++ gcc/passes.c
+@@ -2269,6 +2269,29 @@ override_gate_status (opt_pass *pass, tree func, bool gate_status)
}
-@@ -1492,10 +1492,14 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- insn_info & ii = *i->second;
- if (f != stderr)
-- fprintf (f, "\n\t\t\t\t\t|%d\t", ii.get_index ());
+
++void dump_insns(char const * name)
++{
++ rtx_insn *insn, *next;
++ fprintf(stderr, "====================================\npass: %s\n", name);
++ for (insn = get_insns(); insn; insn = next)
+ {
-+ if (be_very_verbose > 1)
-+ fprintf (f, "\n\t\t\t\t\t|%d\t", ii.get_index ());
-+ else
-+ fprintf (f, "\n\t\t\t\t\t|\t", ii.get_index ());
++ next = NEXT_INSN(insn);
++ debug_rtx(insn);
++#if 0
++ if (NONJUMP_INSN_P (insn))
++ {
++ rtx set= single_set (insn);
++ if (!set)
++ continue;
++
++ if (amiga_is_const_pic_ref(SET_SRC(set)) && MEM_P(SET_DEST(set)))
++ debug_rtx(insn);
++ }
++#endif
+ }
++}
++
++
+ /* Execute PASS. */
-- fprintf (f, "%c ",
-- ii.is_stack () ? 's' : ii.in_proepi () == IN_PROLOGUE ? 'p' : ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
-+ fprintf (f, "%c ", ii.in_proepi () == IN_PROLOGUE ? 'p' : ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
-
- for (int j = 0; j < 8; ++j)
- if (ii.is_use (j) || ii.is_def (j))
-@@ -1829,15 +1833,16 @@ update_insns ()
- jump_table = 0;
- ii.set_proepi (inproepilogue = IN_CODE);
- if (infos.size () > 1)
-- scan_starts.insert (infos.size () - 2);
-+ scan_starts.insert (infos.size () - 1);
- }
- else if (CALL_P(insn))
- {
-- if (insn->jump) {
-- ii.set_proepi (IN_EPILOGUE);
-- ii.mark_jump();
-- scan_starts.insert (infos.size () - 1);
-- }
-+ if (insn->jump)
-+ {
-+ ii.set_proepi (IN_EPILOGUE);
-+ ii.mark_jump ();
-+ scan_starts.insert (infos.size () - 1);
-+ }
- ii.mark_call ();
- if (inproepilogue)
- {
-@@ -2114,6 +2119,7 @@ opt_reg_rename (void)
- int newregno = bit2regno (mask);
-
- /* check the renamed insns. */
-+ std::vector<unsigned> positions;
- std::vector<std::pair<rtx *, rtx> > locs;
- std::vector<std::pair<rtx *, rtx> > patch;
- bool ok = true;
-@@ -2138,6 +2144,7 @@ opt_reg_rename (void)
- *j->first = j->second;
- }
+ bool
+@@ -2278,6 +2301,9 @@ execute_one_pass (opt_pass *pass)
-+ positions.push_back (*i);
- locs.clear ();
- }
- }
-@@ -2148,6 +2155,14 @@ opt_reg_rename (void)
- log ("(r) opt_reg_rename %s -> %s (%d locs, start at %d)\n", reg_names[oldregno], reg_names[newregno],
- patch.size (), index);
+ bool gate_status;
-+ if (be_verbose)
-+ {
-+ for (std::vector<unsigned>::iterator i = positions.begin (); i != positions.end (); ++i)
-+ printf ("%d ", *i);
-+ printf ("\n");
-+ fflush (stdout);
-+ }
++ if (string_bbb_opts && strchr (string_bbb_opts, 'Y'))
++ dump_insns(pass->name);
+
- /* apply all changes. */
- for (std::vector<std::pair<rtx *, rtx> >::iterator j = patch.begin (); j != patch.end (); ++j)
- *j->first = j->second;
-@@ -3716,7 +3731,7 @@ opt_elim_dead_assign (void)
- ++change_count;
- continue;
- }
-- if (ii.get_src_op () == 0 && ii.get_dst_reg () && !ii.is_use(ii.get_dst_regno()))
-+ if (ii.get_src_op () == 0 && ii.get_dst_reg () && !ii.is_use (ii.get_dst_regno ()))
- {
- rtx cached_value = ii.get_track_var ()->get_values ()[ii.get_dst_regno ()];
- rtx cached_value2 = 0;
-@@ -4150,8 +4165,12 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
-- be_very_verbose = strchr (string_bbb_opts, 'V');
-- be_verbose = be_very_verbose || strchr (string_bbb_opts, 'v');
-+ be_very_verbose = strchr (string_bbb_opts, 'V') != 0;
-+ be_verbose = strchr (string_bbb_opts, 'v') != 0;
-+ if (be_verbose && be_very_verbose)
-+ ++be_very_verbose;
-+ if (be_very_verbose)
-+ be_verbose = true;
+ /* IPA passes are executed on whole program, so cfun should be NULL.
+ Other passes need function context set. */
+ if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
+diff --git a/gcc/passes.def b/gcc/passes.def
+index 7db9c9577cf4..61d0e4d47377 100644
+--- gcc/passes.def
++++ gcc/passes.def
+@@ -386,6 +386,7 @@ along with GCC; see the file COPYING3. If not see
+ NEXT_PASS (pass_gen_hsail);
- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-
-From acdf0eba2196c10905cc07af78fba0eca5f457ca Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 22 Jun 2017 15:21:40 +0200
-Subject: [PATCH 193/303] @B support trap and preserve all registers
-
----
- gcc/bbb-opts.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 8b49637f6c09..35ebc7d770e6 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -979,6 +979,13 @@ insn_info::scan_rtx (rtx x)
- return;
- }
+ NEXT_PASS (pass_expand);
++ NEXT_PASS (pass_bbb_baserel);
-+ if (code == TRAP_IF)
-+ {
-+ /* mark all registers used. */
-+ hard = use = myuse = (1 << FIRST_PSEUDO_REGISTER) - 1;
-+ return;
-+ }
+ NEXT_PASS (pass_rest_of_compilation);
+ PUSH_INSERT_PASSES_WITHIN (pass_rest_of_compilation)
+@@ -458,6 +459,7 @@ along with GCC; see the file COPYING3. If not see
+ NEXT_PASS (pass_cprop_hardreg);
+ NEXT_PASS (pass_fast_rtl_dce);
+ NEXT_PASS (pass_reorder_blocks);
++ NEXT_PASS (pass_bbb_optimizations);
+ NEXT_PASS (pass_branch_target_load_optimize2);
+ NEXT_PASS (pass_leaf_regs);
+ NEXT_PASS (pass_split_before_sched2);
+diff --git a/gcc/recog.c b/gcc/recog.c
+index 92b2aa31a777..73d1fd1b1336 100644
+--- gcc/recog.c
++++ gcc/recog.c
+@@ -3252,6 +3252,7 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
+ /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
+ match more than one insn, or to be split into more than one insn. */
+ old_insn = peep2_insn_data[peep2_current].insn;
+
- const char *fmt = GET_RTX_FORMAT(code);
- for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ if (RTX_FRAME_RELATED_P (old_insn))
{
-
-From dccd1ea371e35241057b86bdf90cf8be60d2083c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 22 Jun 2017 16:00:20 +0200
-Subject: [PATCH 194/303] @V bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index e907b4926b96..95b694bea9d1 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170621-133511
-+20170622-160003
-
-From 95ee80db20652f6647cf6f30da3c7c74e7160a62 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 22 Jun 2017 16:01:04 +0200
-Subject: [PATCH 195/303] @B eliminate sp assignments after stack frame
- handling is done
-
----
- gcc/bbb-opts.c | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 35ebc7d770e6..f50c8578f923 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3715,7 +3715,7 @@ track_regs ()
- * delete those insns.
- */
- static unsigned
--opt_elim_dead_assign (void)
-+opt_elim_dead_assign (unsigned blocked_regno)
- {
- track_regs ();
-
-@@ -3731,14 +3731,15 @@ opt_elim_dead_assign (void)
- if (!set)
- continue;
-
-- if (ii.get_dst_reg () && is_reg_dead (ii.get_dst_regno (), index))
-+ if (ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno && is_reg_dead (ii.get_dst_regno (), index))
- {
- log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]);
- SET_INSN_DELETED(insn);
- ++change_count;
- continue;
- }
-- if (ii.get_src_op () == 0 && ii.get_dst_reg () && !ii.is_use (ii.get_dst_regno ()))
-+ if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno
-+ && !ii.is_use (ii.get_dst_regno ()))
- {
- rtx cached_value = ii.get_track_var ()->get_values ()[ii.get_dst_regno ()];
- rtx cached_value2 = 0;
-@@ -4222,7 +4223,7 @@ namespace
- if (do_absolute && opt_absolute ())
- done = 0, update_insns ();
+ bool any_note = false;
+diff --git a/gcc/regrename.c b/gcc/regrename.c
+old mode 100644
+new mode 100755
+index 9643f328ea3e..1ed6557ee713
+--- gcc/regrename.c
++++ gcc/regrename.c
+@@ -374,44 +374,45 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
+ = (enum reg_class) targetm.preferred_rename_class (super_class);
-- if (do_elim_dead_assign && opt_elim_dead_assign ())
-+ if (do_elim_dead_assign && opt_elim_dead_assign (STACK_POINTER_REGNUM))
- done = 0, update_insns ();
+ /* Pick and check the register from the tied chain iff the tied chain
+- is not renamed. */
++ is not renamed. */
+ if (this_head->tied_chain && !this_head->tied_chain->renamed
+ && check_new_reg_p (old_reg, this_head->tied_chain->regno,
+ this_head, *unavailable))
+ return this_head->tied_chain->regno;
- if (do_autoinc && opt_autoinc ())
-@@ -4246,6 +4247,10 @@ namespace
- if (opt_shrink_stack_frame ())
- update_insns ();
- }
-+
-+ /* elim stack pointer stuff last. */
-+ if (do_elim_dead_assign)
-+ opt_elim_dead_assign (FIRST_PSEUDO_REGISTER);
- }
- if (r && be_verbose)
- log ("no bbb optimization code %d\n", r);
-
-From 335edd4fe233548c3353bd7e49fd374fefb6b67c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Jul 2017 09:10:22 +0200
-Subject: [PATCH 196/303] @B fixed regrename: start search was not triggered if
- the assignment is before a label
-
----
- gcc/bbb-opts.c | 26 +++++++++++++-------------
- 1 file changed, 13 insertions(+), 13 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f50c8578f923..247fc522aaa2 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1922,17 +1922,13 @@ is_reg_touched_between (unsigned regno, int from, int to)
- * search backward and find the initial assignment for that regno.
- */
- static unsigned
--find_start (std::set<unsigned> & found, unsigned start, unsigned rename_regno)
-+find_start (unsigned start, unsigned rename_regno)
- {
- /* search the start. */
- while (start > 0)
+ /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
+- over registers that belong to PREFERRED_CLASS and try to find the
+- best register within the class. If that failed, we iterate in
+- the second pass over registers that don't belong to the class.
+- If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
+- ascending order without any preference. */
++ over registers that belong to PREFERRED_CLASS and try to find the
++ best register within the class. If that failed, we iterate in
++ the second pass over registers that don't belong to the class.
++ If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
++ ascending order without any preference. */
+ has_preferred_class = (preferred_class != NO_REGS);
+ for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
{
- unsigned startm1 = start - 1;
-
--// /* already searched. */
--// if (found.find (startm1) != found.end ())
--// break;
--
- /* do not run over RETURNS */
- insn_info & jj = infos[start];
-
-@@ -1995,6 +1991,7 @@ opt_reg_rename (void)
- unsigned runpos = *todo.begin ();
- todo.erase (todo.begin ());
-
-+// printf ("runpos %d \n", runpos); fflush (stdout);
- for (unsigned pos = runpos; mask && pos < infos.size (); ++pos)
- {
- /* already searched. */
-@@ -2020,19 +2017,19 @@ opt_reg_rename (void)
- break;
- }
-
-- unsigned start = j->second->get_index ();
-- if (found.find (start) != found.end () || !infos[start].is_use (rename_regno))
-+ unsigned startat = j->second->get_index ();
-+ if (found.find (startat) != found.end () || !infos[startat].is_use (rename_regno))
- continue;
-
--// printf ("label %d <- %d jump\n", pos, start); fflush (stdout);
+ int new_reg;
+- for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
+- {
+- if (has_preferred_class
++ for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
++ {
++ if (has_preferred_class
+ && (pass == 0)
+ != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
+- new_reg))
+- continue;
++ new_reg))
++ continue;
-- start = find_start (found, start, rename_regno);
-+ unsigned start = find_start (startat, rename_regno);
-+// printf ("label %d <- jump %d : start %d\n", pos, startat, start); fflush (stdout);
- todo.insert (start);
- }
+- if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
+- continue;
++ if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
++ continue;
- /* if this label is at a start, check if it is reachable from the previous insn,
- * and if, check for use then search start. */
-- if (pos == runpos && pos > 0)
-+ if (pos > 0)
- {
- insn_info & bb = infos[pos - 1];
- rtx set = single_set (bb.get_insn ());
-@@ -2040,10 +2037,13 @@ opt_reg_rename (void)
- || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) != IF_THEN_ELSE))
- continue;
+- if (!best_rename)
+- return new_reg;
++ if (!best_rename)
++ return new_reg;
-- if (bb.is_use (rename_regno))
-+// printf ("label start check %d use %d\n", pos, bb.is_use (rename_regno) || bb.is_def(rename_regno)); fflush (stdout);
+- /* In the first pass, we force the renaming of registers that
+- don't belong to PREFERRED_CLASS to registers that do, even
+- though the latters were used not very long ago. */
+- if ((pass == 0
++ /* In the first pass, we force the renaming of registers that
++ don't belong to PREFERRED_CLASS to registers that do, even
++ though the latters were used not very long ago.
++ Also use a register if no best_new_reg was found till now */
++ if (((pass == 0 || !has_preferred_class)
+ && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
+ best_new_reg))
+ || tick[best_new_reg] > tick[new_reg])
+- best_new_reg = new_reg;
++ best_new_reg = new_reg;
+ }
+ if (pass == 0 && best_new_reg != old_reg)
+ break;
+@@ -897,7 +898,7 @@ regrename_analyze (bitmap bb_mask)
+ if (!range_overlaps_hard_reg_set_p (live, chain->regno,
+ chain->nregs))
+ continue;
+-
+
-+ if (bb.is_use (rename_regno) || bb.is_def(rename_regno))
- {
-- unsigned start = find_start (found, pos - 1, rename_regno);
-+ unsigned start = find_start (pos - 1, rename_regno);
- todo.insert (start);
-+// printf ("label %d : start %d \n", pos, start); fflush (stdout);
- }
- }
+ n_succs_used++;
-@@ -2094,7 +2094,7 @@ opt_reg_rename (void)
- insn_info & bb = infos[label_index + 1];
- if (found.find (label_index) == found.end () && bb.is_use (rename_regno))
- {
--// printf ("jump %d -> %d label\n", pos, label_index); fflush (stdout);
-+// printf ("jump %d -> label %d \n", pos, label_index); fflush (stdout);
- todo.insert (label_index);
+ dest_ri = (struct bb_rename_info *)e->dest->aux;
+@@ -921,7 +922,7 @@ regrename_analyze (bitmap bb_mask)
+ printed = true;
+ fprintf (dump_file,
+ " merging chains %d (->%d) and %d (->%d) [%s]\n",
+- k, incoming_chain->id, j, chain->id,
++ k, incoming_chain->id, j, chain->id,
+ reg_names[incoming_chain->regno]);
}
- }
-
-From 5180bf61c8f24d190fe51722d78f69b4fb566065 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 5 Jul 2017 20:20:50 +0200
-Subject: [PATCH 197/303] @B add ctype<char>::~ctype()
-
----
- libstdc++-v3/config/os/newlib/ctype_configure_char.cc | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/libstdc++-v3/config/os/newlib/ctype_configure_char.cc b/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-index 903de5625d77..3198a3069fc6 100644
---- libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-+++ libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-@@ -65,6 +65,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
- _M_narrow_ok = 0;
- }
-+ ctype<char>::~ctype()
-+ {
-+ }
-+
- char
- ctype<char>::do_toupper(char __c) const
- {
-
-From f088c99da4c5cdb2b86c57475a2fddbb76deba6f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 6 Jul 2017 23:38:50 +0200
-Subject: [PATCH 198/303] @B resolve ctype vtable issue and avoid duplicate
- definition
-
----
- libstdc++-v3/config/os/newlib/ctype_configure_char.cc | 5 +++++
- libstdc++-v3/configure.host | 4 ++--
- libstdc++-v3/src/c++11/ctype.cc | 3 +++
- 3 files changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/libstdc++-v3/config/os/newlib/ctype_configure_char.cc b/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-index 3198a3069fc6..5543759efa51 100644
---- libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-+++ libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-@@ -65,9 +65,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
- _M_narrow_ok = 0;
- }
-
-+#ifdef TARGET_AMIGA
- ctype<char>::~ctype()
- {
-+ _S_destroy_c_locale(_M_c_locale_ctype);
-+ if (_M_del)
-+ delete[] this->table();
- }
-+#endif
-
- char
- ctype<char>::do_toupper(char __c) const
-diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
-index 354b1c7ead46..13444bc5a4cf 100644
---- libstdc++-v3/configure.host
-+++ libstdc++-v3/configure.host
-@@ -228,8 +228,8 @@ case "${host_os}" in
- ;;
- amiga*)
- os_include_dir="os/newlib"
-- CXXFLAGS="${CXXFLAGS} -noixemul"
-- CPPFLAGS="${CPPFLAGS} -noixemul"
-+# CXXFLAGS="${CXXFLAGS} -noixemul"
-+# CPPFLAGS="${CPPFLAGS} -noixemul"
- ;;
- bsd*)
- # Plain BSD attempts to share FreeBSD files.
-diff --git a/libstdc++-v3/src/c++11/ctype.cc b/libstdc++-v3/src/c++11/ctype.cc
-index fa370681dad5..6867e61e8b7d 100644
---- libstdc++-v3/src/c++11/ctype.cc
-+++ libstdc++-v3/src/c++11/ctype.cc
-@@ -51,12 +51,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- const size_t ctype<char>::table_size;
-
-+#ifndef TARGET_AMIGA
-+/* moved to ctype_configure_char */
- ctype<char>::~ctype()
- {
- _S_destroy_c_locale(_M_c_locale_ctype);
- if (_M_del)
- delete[] this->table();
- }
-+#endif
+@@ -954,7 +955,7 @@ regrename_analyze (bitmap bb_mask)
+ numbering in its subpatterns. */
- // Fill in the narrowing cache and flag whether all values are
- // valid or not. _M_narrow_ok is set to 2 if memcpy can't
-
-From c4e78d720943ce032d2ccfff2ceea56164403d29 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 7 Jul 2017 21:57:40 +0200
-Subject: [PATCH 199/303] @B restore -noixemul in libstdc++v3
-
----
- gcc/DATESTAMP | 2 +-
- libstdc++-v3/configure.host | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 95b694bea9d1..58e8c652ab1b 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170622-160003
-+20170707-215619
-diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
-index 13444bc5a4cf..354b1c7ead46 100644
---- libstdc++-v3/configure.host
-+++ libstdc++-v3/configure.host
-@@ -228,8 +228,8 @@ case "${host_os}" in
- ;;
- amiga*)
- os_include_dir="os/newlib"
--# CXXFLAGS="${CXXFLAGS} -noixemul"
--# CPPFLAGS="${CPPFLAGS} -noixemul"
-+ CXXFLAGS="${CXXFLAGS} -noixemul"
-+ CPPFLAGS="${CPPFLAGS} -noixemul"
- ;;
- bsd*)
- # Plain BSD attempts to share FreeBSD files.
-
-From 0fe16b4eac1770fc611f217ca4c9aafdb0065f7e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 7 Jul 2017 23:01:11 +0200
-Subject: [PATCH 200/303] @B fix v2 ctype dtor
-
----
- libstdc++-v3/config/os/newlib/ctype_configure_char.cc | 2 +-
- libstdc++-v3/src/c++11/ctype.cc | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libstdc++-v3/config/os/newlib/ctype_configure_char.cc b/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-index 5543759efa51..ed0c757d42f8 100644
---- libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-+++ libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-@@ -65,7 +65,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
- _M_narrow_ok = 0;
- }
+ bool
+-regrename_do_replace (struct du_head *head, int reg)
++regrename_do_replace (struct du_head *head, int regno)
+ {
+ struct du_chain *chain;
+ unsigned int base_regno = head->regno;
+@@ -962,19 +963,20 @@ regrename_do_replace (struct du_head *head, int reg)
--#ifdef TARGET_AMIGA
-+#ifdef __AMIGA__
- ctype<char>::~ctype()
- {
- _S_destroy_c_locale(_M_c_locale_ctype);
-diff --git a/libstdc++-v3/src/c++11/ctype.cc b/libstdc++-v3/src/c++11/ctype.cc
-index 6867e61e8b7d..f80e83034255 100644
---- libstdc++-v3/src/c++11/ctype.cc
-+++ libstdc++-v3/src/c++11/ctype.cc
-@@ -51,7 +51,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+ for (chain = head->first; chain; chain = chain->next_use)
+ {
+- unsigned int regno = ORIGINAL_REGNO (*chain->loc);
+- struct reg_attrs *attr = REG_ATTRS (*chain->loc);
+- int reg_ptr = REG_POINTER (*chain->loc);
++ unsigned int orig_regno = ORIGINAL_REGNO(*chain->loc);
++ struct reg_attrs *attr = REG_ATTRS(*chain->loc);
++ int reg_ptr = REG_POINTER(*chain->loc);
- const size_t ctype<char>::table_size;
+ if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
+- validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
+- gen_rtx_UNKNOWN_VAR_LOC (), true);
++ validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC(chain->insn)),
++ gen_rtx_UNKNOWN_VAR_LOC (),
++ true);
+ else
+ {
+- validate_change (chain->insn, chain->loc,
+- gen_raw_REG (GET_MODE (*chain->loc), reg), true);
+- if (regno >= FIRST_PSEUDO_REGISTER)
+- ORIGINAL_REGNO (*chain->loc) = regno;
++ validate_change (chain->insn, chain->loc,
++ gen_raw_REG (GET_MODE(*chain->loc), regno), true);
++ if (orig_regno >= FIRST_PSEUDO_REGISTER)
++ ORIGINAL_REGNO (*chain->loc) = orig_regno;
+ REG_ATTRS (*chain->loc) = attr;
+ REG_POINTER (*chain->loc) = reg_ptr;
+ }
+@@ -983,10 +985,29 @@ regrename_do_replace (struct du_head *head, int reg)
+ if (!apply_change_group ())
+ return false;
--#ifndef TARGET_AMIGA
-+#ifndef __AMIGA__
- /* moved to ctype_configure_char */
- ctype<char>::~ctype()
- {
-
-From 8e243494b547e0452be69f9decc094f5cdf390db Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:26:30 +0200
-Subject: [PATCH 201/303] @B fixed opt_const_cmp_to_sub with chained compares:
- exit labels were not tested.
-
----
- gcc/bbb-opts.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 247fc522aaa2..365eec1c7280 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2717,6 +2717,15 @@ opt_const_cmp_to_sub (void)
- if (pp.get_dst_regno () != i1.get_dst_regno ())
- continue;
- lastsubval = pp.get_src_intval ();
+- mode = GET_MODE (*head->first->loc);
++ mode = GET_MODE(*head->first->loc);
+ head->renamed = 1;
+- head->regno = reg;
+- head->nregs = hard_regno_nregs[reg][mode];
++ head->regno = regno;
++ head->nregs = hard_regno_nregs[regno][mode];
+
-+ // but still check for usage after this jump
-+ j2l_iterator l = jump2label.find(index + 2);
-+ if (l == jump2label.end())
-+ continue;
++ /* SBF: also update the current df info, move from base_regno -> regno. */
++ if (base_regno < FIRST_PSEUDO_REGISTER && regno < FIRST_PSEUDO_REGISTER)
++ for (chain = head->first; chain; chain = chain->next_use)
++ {
++ if (DEBUG_INSN_P (chain->insn) && VAR_LOC_UNKNOWN_P(INSN_VAR_LOCATION_LOC(chain->insn)))
++ continue;
++ /* undo regno patch - will be patched again */
++ if (REGNO (*chain->loc) == regno)
++ SET_REGNO(*chain->loc, base_regno);
++ df_ref_change_reg_with_loc (*chain->loc, regno);
+
-+ insn_info & label = infos[l->second + 1];
-+ if (label.is_use (i1.get_dst_regno ()))
-+ continue;
- }
- else if (!is_reg_dead (i1.get_dst_regno (), index))
- continue;
-@@ -2752,9 +2761,8 @@ opt_const_cmp_to_sub (void)
- if (!i2.is_jump ())
- continue;
++ SET_REGNO(*chain->loc, regno);
++ }
++
++ /* Mark the old regno as no longer used. */
++ if (!df->hard_regs_live_count[base_regno])
++ df_set_regs_ever_live (base_regno, false);
++
+ return true;
+ }
-- rtx_insn * jump = i2.get_insn ();
-- rtx jmppattern = PATTERN (jump);
-- if (GET_RTX_LENGTH (GET_CODE(jmppattern)) < 2)
-+ rtx jmppattern = single_set (i2.get_insn ());
-+ if (!jmppattern)
- continue;
+@@ -1912,7 +1933,6 @@ const pass_data pass_data_regrename =
+ 0, /* todo_flags_start */
+ TODO_df_finish, /* todo_flags_finish */
+ };
+-
+ class pass_regrename : public rtl_opt_pass
+ {
+ public:
+@@ -1923,7 +1943,7 @@ class pass_regrename : public rtl_opt_pass
+ /* opt_pass methods: */
+ virtual bool gate (function *)
+ {
+- return (optimize > 0 && (flag_rename_registers));
++ return (optimize > 0 && (flag_rename_registers) && !TARGET_AMIGA);
+ }
- rtx jmpsrc = XEXP(jmppattern, 1);
-
-From be3b4203f780465f6221fe829df769638bb989c6 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:27:44 +0200
-Subject: [PATCH 202/303] @N create labels and storage needed for exception
- handling
-
----
- gcc/dwarf2out.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
-index 1357bf24a125..566aaaf4e370 100644
---- gcc/dwarf2out.c
-+++ gcc/dwarf2out.c
-@@ -469,6 +469,16 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
- eh_frame_section = ((flags == SECTION_WRITE)
- ? data_section : readonly_data_section);
- #endif /* EH_FRAME_SECTION_NAME */
+ virtual unsigned int execute (function *) { return regrename_optimize (); }
+diff --git a/gcc/target-def.h b/gcc/target-def.h
+index ec5e09e568e6..9fbfde121095 100644
+--- gcc/target-def.h
++++ gcc/target-def.h
+@@ -108,3 +108,11 @@
+ #include "hooks.h"
+ #include "targhooks.h"
+ #include "insn-target-def.h"
+
-+#ifdef TARGET_AMIGA
-+ switch_to_section (data_section);
-+ fputs("\t__EH_FRAME_OBJECT__:\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long 0\n", asm_out_file);
-+ fputs("\t.stabs \"__EH_FRAME_OBJECTS__\",24,0,0,__EH_FRAME_OBJECT__\n", asm_out_file);
++#ifndef TARGET_GCC_EXCEPT_TABLE
++#define TARGET_GCC_EXCEPT_TABLE ".gcc_except_table"
++#endif
+
-+ switch_to_section (eh_frame_section);
-+ ASM_OUTPUT_LABEL (asm_out_file, "_EH_FRAME_BEGIN__");
-+ fputs("\t.stabs \"__EH_FRAME_BEGINS__\",22,0,0,__EH_FRAME_BEGIN__\n", asm_out_file);
++#ifndef TARGET_GCC_EXCEPT_TABLE_S
++#define TARGET_GCC_EXCEPT_TABLE_S ".gcc_except_table.%s"
+#endif
- }
+diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
+index 28dac22add66..16aa71ca4ee4 100644
+--- gcc/tree-chkp.c
++++ gcc/tree-chkp.c
+@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
+ #include "system.h"
+ #include "coretypes.h"
+ #include "backend.h"
++#include "tm_p.h"
+ #include "target.h"
+ #include "rtl.h"
+ #include "tree.h"
+diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
+index 5f5055d3a6c1..76c0996850f4 100644
+--- gcc/tree-pass.h
++++ gcc/tree-pass.h
+@@ -590,6 +590,8 @@ extern rtl_opt_pass *make_pass_branch_target_load_optimize2 (gcc::context
+ *ctxt);
+ extern rtl_opt_pass *make_pass_leaf_regs (gcc::context *ctxt);
+ extern rtl_opt_pass *make_pass_split_before_sched2 (gcc::context *ctxt);
++extern rtl_opt_pass *make_pass_bbb_optimizations (gcc::context *ctxt);
++extern rtl_opt_pass *make_pass_bbb_baserel (gcc::context *ctxt);
+ extern rtl_opt_pass *make_pass_compare_elim_after_reload (gcc::context *ctxt);
+ extern rtl_opt_pass *make_pass_sched2 (gcc::context *ctxt);
+ extern rtl_opt_pass *make_pass_stack_regs (gcc::context *ctxt);
+diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
+index 9f09d30b1f91..ab9c0117b078 100644
+--- gcc/var-tracking.c
++++ gcc/var-tracking.c
+@@ -92,10 +92,10 @@
+ #include "target.h"
+ #include "rtl.h"
+ #include "tree.h"
++#include "tm_p.h"
+ #include "cfghooks.h"
+ #include "alloc-pool.h"
+ #include "tree-pass.h"
+-#include "tm_p.h"
+ #include "insn-config.h"
+ #include "regs.h"
+ #include "emit-rtl.h"
+diff --git a/gcc/varasm.c b/gcc/varasm.c
+index b65f29c13a46..8ead5ec3fcbb 100644
+--- gcc/varasm.c
++++ gcc/varasm.c
+@@ -252,7 +252,6 @@ get_unnamed_section (unsigned int flags, void (*callback) (const void *),
+ sect->unnamed.callback = callback;
+ sect->unnamed.data = data;
+ sect->unnamed.next = unnamed_sections;
+-
+ unnamed_sections = sect;
+ return sect;
+ }
+@@ -2228,11 +2227,17 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
+ else
+ {
+ /* Special-case handling of vtv comdat sections. */
+- if (sect->named.name
++ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED && sect->named.name
+ && (strcmp (sect->named.name, ".vtable_map_vars") == 0))
+ handle_vtv_comdat_section (sect, decl);
+ else
+- switch_to_section (sect);
++ {
++#ifdef TARGET_AMIGA
++ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED)
++ sect->named.decl = decl;
++#endif
++ switch_to_section (sect);
++ }
+ if (align > BITS_PER_UNIT)
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
+ assemble_variable_contents (decl, name, dont_output_data);
+@@ -4962,7 +4967,7 @@ output_constructor_regular_field (oc_local_state *local)
+ if each element has the proper size. */
+ if (local->field != NULL_TREE || local->index != NULL_TREE)
+ {
+- if (fieldpos > local->total_bytes)
++ if (fieldpos >= local->total_bytes)
+ {
+ assemble_zeros (fieldpos - local->total_bytes);
+ local->total_bytes = fieldpos;
+diff --git a/libcpp/lex.c b/libcpp/lex.c
+index e5a0397f3099..c2131adeb38e 100644
+--- libcpp/lex.c
++++ libcpp/lex.c
+@@ -64,6 +64,10 @@ static tokenrun *next_tokenrun (tokenrun *);
- switch_to_section (eh_frame_section);
-
-From 7c0d506d800c3a33d3a9f8b7da0a5be3e4a72178 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:30:55 +0200
-Subject: [PATCH 203/303] @N create startup code to init exception structures,
- link some glue code (cxxglue) if g++ is used to init exceptions.
-
----
- gcc/cp/g++spec.c | 16 +++++++++++++++-
- libgcc/config/m68k/cxxglue.c | 22 ++++++++++++++++++++++
- libgcc/config/m68k/t-glue | 5 +++++
- 3 files changed, 42 insertions(+), 1 deletion(-)
- create mode 100644 libgcc/config/m68k/cxxglue.c
- create mode 100644 libgcc/config/m68k/t-glue
-
-diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
-index 03cbde090cb3..c6fc90d546d6 100644
---- gcc/cp/g++spec.c
-+++ gcc/cp/g++spec.c
-@@ -262,7 +262,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
- #endif
+ static _cpp_buff *new_buff (size_t);
- /* Add one for shared_libgcc or extra static library. */
-- num_args = argc + added + need_math + (library > 0) * 4 + 1;
-+ num_args = argc + added + need_math + (library > 0) * 5 + 1;
- new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
++/*
++ * SBF: This flag is set if an asm statement is parsed, to support multiline strings in __asm()
++ */
++int in_assembler_directive;
- i = 0;
-@@ -347,6 +347,20 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
- CL_DRIVER, &new_decoded_options[j]);
- added_libraries++;
- j++;
-+
-+#ifdef TARGET_AMIGA
+ /* Utility routine:
+
+@@ -1063,7 +1067,10 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
+ else if (note->type == 0)
+ /* Already processed in lex_raw_string. */;
+ else
+- abort ();
+ {
-+ extern const char *
-+ amiga_m68k_prefix_func (int argc, const char ** argv);
-+ char const * cxxglue = "../lib/gcc/m68k-amigaos/"
-+ DEFAULT_TARGET_VERSION
-+ "/cxxglue.o";
-+ char const * p = amiga_m68k_prefix_func (1, &cxxglue);
-+ generate_option_input_file (p, &new_decoded_options[j]);
-+ ++j;
++// abort ();
++ printf("ups: note type=%d\n", note->type);
+ }
-+#endif
-+
- /* Add target-dependent static library, if necessary. */
- if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
- {
-diff --git a/libgcc/config/m68k/cxxglue.c b/libgcc/config/m68k/cxxglue.c
-new file mode 100644
-index 000000000000..2a4e6374d088
---- /dev/null
-+++ libgcc/config/m68k/cxxglue.c
-@@ -0,0 +1,22 @@
-+#include "stabs.h"
-+
-+extern void __register_frame_info(void *, void *);
-+extern void * _EH_FRAME_BEGINS__;
-+extern void * _EH_FRAME_OBJECTS__;
-+
-+void __init_eh() {
-+ void ** frame = &_EH_FRAME_BEGINS__;
-+ void ** object = &_EH_FRAME_OBJECTS__;
-+
-+ int n = *(int *)frame++;
-+ int m = *(int *)object++;
-+ if (n != m)
-+ return;
-+
-+ while (n--) {
-+ __register_frame_info(*frame++, *object++);
-+ }
-+}
-+
-+ADD2INIT(__init_eh,127);
-+
-diff --git a/libgcc/config/m68k/t-glue b/libgcc/config/m68k/t-glue
-new file mode 100644
-index 000000000000..e65335f2e5f7
---- /dev/null
-+++ libgcc/config/m68k/t-glue
-@@ -0,0 +1,5 @@
-+cxxglue.o: $(srcdir)/config/m68k/cxxglue.c
-+ $(CC) $(CFLAGS) -c $<
-+
-+EXTRA_PARTS=cxxglue.o
-+
-
-From 54f7a6eb27c74a7f4358a32c4f018ca12512bab0 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:38:25 +0200
-Subject: [PATCH 204/303] @R do not add cxxglue if -fno-exceptions is specified
-
----
- gcc/cp/g++spec.c | 26 ++++++++++++++++++--------
- 1 file changed, 18 insertions(+), 8 deletions(-)
-
-diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
-index c6fc90d546d6..0bc7d4f78018 100644
---- gcc/cp/g++spec.c
-+++ gcc/cp/g++spec.c
-@@ -350,14 +350,24 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ }
+ }
- #ifdef TARGET_AMIGA
+@@ -1875,6 +1882,20 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
+ break;
+ else if (c == '\n')
{
-- extern const char *
-- amiga_m68k_prefix_func (int argc, const char ** argv);
-- char const * cxxglue = "../lib/gcc/m68k-amigaos/"
-- DEFAULT_TARGET_VERSION
-- "/cxxglue.o";
-- char const * p = amiga_m68k_prefix_func (1, &cxxglue);
-- generate_option_input_file (p, &new_decoded_options[j]);
-- ++j;
-+ bool addglue = true;
-+ /* do not add glue if exceptions are disabled. */
-+ for (int ii = 0; ii < argc; ++ii)
-+ {
-+ if (decoded_options[ii].opt_index == OPT_fexceptions)
-+ addglue = decoded_options[ii].opt_index;
-+ }
-+ if (addglue)
++ /*
++ * SBF: allow multi-line strings
++ * Ignore the line end and move to next line.
++ * Only fail, if there is no next line
++ */
++ if (in_assembler_directive)
+ {
-+ extern const char *
-+ amiga_m68k_prefix_func (int argc, const char ** argv);
-+ char const * cxxglue = "../lib/gcc/m68k-amigaos/"
-+ DEFAULT_TARGET_VERSION
-+ "/cxxglue.o";
-+ char const * p = amiga_m68k_prefix_func (1, &cxxglue);
-+ generate_option_input_file (p, &new_decoded_options[j]);
-+ ++j;
++ cpp_buffer *buffer = pfile->buffer;
++ if (buffer->cur < buffer->rlimit)
++ CPP_INCREMENT_LINE (pfile, 0);
++ buffer->need_line = true;
++ if (_cpp_get_fresh_line (pfile))
++ continue;
+ }
- }
- #endif
-
-
-From 68afa4d4843d806f89436406aa175babaf951e33 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:42:57 +0200
-Subject: [PATCH 205/303] @R enable cxxglue
-
----
- libgcc/Makefile.in | 4 ++--
- libgcc/config.host | 2 +-
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
+ cur--;
+ /* Unmatched quotes always yield undefined behavior, but
+ greedy lexing means that what appears to be an unterminated
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index f09b39b0e85f..39f91d1567b6 100644
--- libgcc/Makefile.in
@@ -34390,625 +10419,51 @@ index f09b39b0e85f..39f91d1567b6 100644
-fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
-fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \
diff --git a/libgcc/config.host b/libgcc/config.host
-index 1478faa2b027..0fa6eab77340 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -817,7 +817,7 @@ m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
- m68k-*-amiga*)
--# tmake_file="$tmake_file m68k/t-floatlib"
-+ tmake_file="$tmake_file m68k/t-cxxglue"
- ;;
- m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
-
-From 3984d072175a725d99fa7fdab7e553f8edf7d413 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:47:04 +0200
-Subject: [PATCH 206/303] @R remove some hard coded -O2 flags
-
----
- libstdc++-v3/configure.host | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
-index 354b1c7ead46..137e15e96d26 100644
---- libstdc++-v3/configure.host
-+++ libstdc++-v3/configure.host
-@@ -228,8 +228,7 @@ case "${host_os}" in
- ;;
- amiga*)
- os_include_dir="os/newlib"
-- CXXFLAGS="${CXXFLAGS} -noixemul"
-- CPPFLAGS="${CPPFLAGS} -noixemul"
-+ CFLAGS="-Os -noixemul"
- ;;
- bsd*)
- # Plain BSD attempts to share FreeBSD files.
-
-From a3f9038954373027f5ff07bf1a694b90dc86bd49 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:47:49 +0200
-Subject: [PATCH 207/303] @N hacked the mechanism to restore the registers
- during excpetion handling
-
----
- libgcc/unwind-dw2.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++--
- libgcc/unwind.inc | 8 ++---
- 2 files changed, 86 insertions(+), 7 deletions(-)
-
-diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
-index 1fb6026d123f..da6e077b7b3c 100644
---- libgcc/unwind-dw2.c
-+++ libgcc/unwind-dw2.c
-@@ -260,6 +260,9 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
- }
-
- /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
-+#ifdef TARGET_AMIGA
-+static int overregs[16];
-+#endif
-
- inline void
- _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
-@@ -271,6 +274,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
- gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
- size = dwarf_reg_size_table[index];
-
-+#ifdef TARGET_AMIGA
-+ overregs[index] = val;
-+#endif
- if (_Unwind_IsExtendedContext (context) && context->by_value[index])
- {
- context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
-@@ -279,6 +285,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
-
- ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
-
-+ if (!ptr)
-+ return;
-+
- if (size == sizeof(_Unwind_Ptr))
- * (_Unwind_Ptr *) ptr = val;
- else
-@@ -1612,10 +1621,10 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
- macro because __builtin_eh_return must be invoked in the context of
- our caller. */
-
--#define uw_install_context(CURRENT, TARGET) \
-+#define uw_install_context(CURRENT, TARGET, INDEX) \
- do \
- { \
-- long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
-+ long offset = uw_install_context_1 ((CURRENT), (TARGET), (INDEX)); \
- void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
- _Unwind_DebugHook ((TARGET)->cfa, handler); \
- __builtin_eh_return (offset, handler); \
-@@ -1624,7 +1633,8 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
-
- static long
- uw_install_context_1 (struct _Unwind_Context *current,
-- struct _Unwind_Context *target)
-+ struct _Unwind_Context *target,
-+ int index ATTRIBUTE_UNUSED)
- {
- long i;
- _Unwind_SpTmp sp_slot;
-@@ -1659,7 +1669,76 @@ uw_install_context_1 (struct _Unwind_Context *current,
- else if (t && c && t != c)
- memcpy (c, t, dwarf_reg_size_table[i]);
- }
-+ }
-+#ifdef __AMIGA__
-+ /* SBF: evil hack to patch the values for d0/d1 into the stack location.
-+ * search the movem insn and count the saved regs.
-+ * Now patch the values into location.
-+ * Always patch d0/d1 since override is always invoked for d0/d1.
-+ * Then patch all other regs which the above code omitted.
-+ */
-+ /* uw_install_context_1 is called from 4 different locations - each uses an unique index.
-+ * So initialization is only done once.
-+ */
-+ static unsigned short counts[4];
-+ static unsigned short masks[4];
-+
-+ unsigned short count = 0;
-+ unsigned short reg_mask = masks[index];
-+ /* init each index once. */
-+ if (!reg_mask)
-+ {
-+ /* get the return address.*/
-+ unsigned short * sp = *(((unsigned short **)&current) - 1);
-+ /* search the movem -x(a5),regs insn.*/
-+ for (;;)
-+ {
-+ unsigned short s = *sp++;
-+// printf("%04x ", s);
-+ gcc_assert(s != (unsigned short)0x4e75);// hit return? ouch!
-+ if (s == (unsigned short)0x4ced)
-+ break;
-+ }
-+ reg_mask = *sp;
-+ /* count saved regs */
-+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
-+ {
-+ if (m & 1)
-+ ++count;
-+ m >>= 1;
-+ }
-+ masks[index] = reg_mask;
-+ counts[index] = count;
-+ }
-+ else
-+ count = counts[index];
-+
-+ /* regs are saved below local vars -> start at current */
-+ int * p = ((int *)current) - count;
-+
-+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
-+ {
-+ if (m & 1)
-+ {
-+ if (i <= 1 || (!current->reg[i] && (target->reg[i] || target->by_value[i])))
-+ {
-+ int old = *p;
-+ /* not set by the code above - set it here */
-+ if (i <= 1) // use the override values for d0/d1
-+ *p = overregs[i];
-+ else
-+ if (target->by_value[i])
-+ *p = (int)target->reg[i];
-+ else
-+ *p = *(int*)target->reg[i];
-+// printf("patch reg %d from %08lx to %08lx\n", i, old, *p);
-+ }
-+ ++p;
-+ }
-+ m >>= 1;
-+ }
-
-+#endif
- /* If the current frame doesn't have a saved stack pointer, then we
- need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
- pointer value reloaded. */
-diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
-index 7413b55e3fab..bf07725ac840 100644
---- libgcc/unwind.inc
-+++ libgcc/unwind.inc
-@@ -132,7 +132,7 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
- if (code != _URC_INSTALL_CONTEXT)
- return code;
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 0);
- }
-
-
-@@ -208,7 +208,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
- if (code != _URC_INSTALL_CONTEXT)
- return code;
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 1);
- }
-
-
-@@ -233,7 +233,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
-
- gcc_assert (code == _URC_INSTALL_CONTEXT);
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 2);
- }
-
-
-@@ -258,7 +258,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
-
- gcc_assert (code == _URC_INSTALL_CONTEXT);
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 3);
- }
-
-
-
-From 1d661106336bf40c63163fcc4e30c9c46b45cf9e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:48:11 +0200
-Subject: [PATCH 208/303] @V bump version
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 58e8c652ab1b..51af5f4da01f 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170707-215619
-+20170711-124202
-
-From af2b3738ed3afb31a0c1aed11cdc5e2d9db3a65b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 11 Jul 2017 12:49:56 +0200
-Subject: [PATCH 209/303] @B fix evaluating -fno-exceptions
-
----
- gcc/cp/g++spec.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
-index 0bc7d4f78018..83a5ab514c79 100644
---- gcc/cp/g++spec.c
-+++ gcc/cp/g++spec.c
-@@ -355,7 +355,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
- for (int ii = 0; ii < argc; ++ii)
- {
- if (decoded_options[ii].opt_index == OPT_fexceptions)
-- addglue = decoded_options[ii].opt_index;
-+ addglue = decoded_options[ii].value;
- }
- if (addglue)
- {
-
-From 11b4ecb7269e55ca24a184e558883aeb5fe33342 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 12 Jul 2017 07:24:02 +0200
-Subject: [PATCH 210/303] @B fix merge ...
-
----
- libgcc/unwind-dw2.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
-index da6e077b7b3c..7bf0e4236f64 100644
---- libgcc/unwind-dw2.c
-+++ libgcc/unwind-dw2.c
-@@ -1669,7 +1669,6 @@ uw_install_context_1 (struct _Unwind_Context *current,
- else if (t && c && t != c)
- memcpy (c, t, dwarf_reg_size_table[i]);
- }
-- }
- #ifdef __AMIGA__
- /* SBF: evil hack to patch the values for d0/d1 into the stack location.
- * search the movem insn and count the saved regs.
-
-From c760f9bdfda61e158d5d71b44d9163f7802d0314 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 12 Jul 2017 09:12:56 +0200
-Subject: [PATCH 211/303] @B fix libstdc++ config
-
----
- libstdc++-v3/configure.host | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
-index 137e15e96d26..fde4a72bd31b 100644
---- libstdc++-v3/configure.host
-+++ libstdc++-v3/configure.host
-@@ -229,6 +229,7 @@ case "${host_os}" in
- amiga*)
- os_include_dir="os/newlib"
- CFLAGS="-Os -noixemul"
-+ CPPFLAGS="-Os -noixemul"
- ;;
- bsd*)
- # Plain BSD attempts to share FreeBSD files.
-
-From bd065307745a5bbf8c56e72d94e291e595103897 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 12 Jul 2017 12:08:05 +0200
-Subject: [PATCH 212/303] change host pattern from m68k-*-amiga to m68k*-amiga
-
----
- libgcc/config.host | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libgcc/config.host b/libgcc/config.host
-index 0fa6eab77340..8e4fb7942f79 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -816,7 +816,7 @@ m32r-*-linux*)
- m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
--m68k-*-amiga*)
-+m68k*-amiga*)
- tmake_file="$tmake_file m68k/t-cxxglue"
- ;;
- m68k-*-elf* | fido-*-elf)
-
-From 17dc596a0d8a232ae647216f27d707010c3e836e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 12 Jul 2017 14:07:28 +0200
-Subject: [PATCH 213/303] fix t-glue makefile name
-
----
- libgcc/config.host | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libgcc/config.host b/libgcc/config.host
-index 8e4fb7942f79..5de7abdb8a95 100644
+index 6f6810cf0baf..7117e7983b53 100644
--- libgcc/config.host
+++ libgcc/config.host
-@@ -816,8 +816,8 @@ m32r-*-linux*)
+@@ -816,6 +816,11 @@ m32r-*-linux*)
m32rle-*-linux*)
tmake_file="$tmake_file m32r/t-linux t-fdpbit"
;;
--m68k*-amiga*)
-- tmake_file="$tmake_file m68k/t-cxxglue"
+m68k-*-amiga*)
-+ tmake_file="$tmake_file m68k/t-glue"
- ;;
++ tmake_file="$tmake_file m68k/t-glue m68k/t-floatlib soft-fp"
++ CFLAGS="-Os"
++# tmake_file="$tmake_file m68k/t-glue soft-fp"
++ ;;
m68k-*-elf* | fido-*-elf)
tmake_file="$tmake_file m68k/t-floatlib"
-
-From cfa7b74b520032da16a32425a6d206cba92d0feb Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 20 Aug 2017 21:40:08 +0200
-Subject: [PATCH 214/303] fix #1: fix inc/erase with iterator
-
----
- gcc/bbb-opts.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 365eec1c7280..99785cf5d6ad 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3608,7 +3608,7 @@ track_regs ()
- j != reg2slot.end () && j->first == k->first;)
- {
- values[j->second] = 0;
-- reg2slot.erase (j++);
-+ j = reg2slot.erase (j);
- }
- }
- }
-@@ -3649,7 +3649,7 @@ track_regs ()
- j != reg2slot.end () && j->first == k->first;)
- {
- values[j->second] = 0;
-- reg2slot.erase (j++);
-+ j = reg2slot.erase (j);
- }
- }
-
-@@ -3670,7 +3670,7 @@ track_regs ()
- j != reg2slot.end () && j->first == k->first;)
- {
- values[j->second] = 0;
-- reg2slot.erase (j++);
-+ j = reg2slot.erase (j);
- }
- }
-
-@@ -3886,9 +3886,9 @@ opt_absolute (void)
- bool k_src = kk.is_src_mem () && (kk.has_src_addr () || kk.get_src_symbol ()) && !kk.has_src_memreg ()
- && kk.get_src_symbol () == with_symbol;
- if (k_dst && kk.get_dst_addr () - base > 0x7ffc)
-- found.erase (k++);
-+ k = found.erase (k);
- else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
-- found.erase (k++);
-+ k = found.erase (k);
- else
- ++k;
- }
-
-From 13bdc411c4eb3fcec280affc02b38e8e7b29e7d4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 21 Aug 2017 17:49:51 +0200
-Subject: [PATCH 215/303] fix printing baserel insns, avoid combines resulting
- in 'not pic_reg'
-
----
- gcc/config/m68k/amigaos.c | 32 ++++++++++++++++++++++++++++++++
- gcc/config/m68k/amigaos.h | 5 +++++
- gcc/config/m68k/m68k.c | 2 +-
- 3 files changed, 38 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index dc2f2ac74369..6aee22fa3720 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -885,3 +885,35 @@ amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
- return 0;
- }
-
-+/*
-+ * decline src like:
-+(plus:SI (reg/f:SI 0 d0 [210])
-+ (const:SI (minus:SI (not:SI (reg:SI 12 a4))
-+ *
-+ */
-+bool
-+amigaos_legitimate_combined_insn (rtx_insn * insn)
-+{
-+ rtx set = single_set(insn);
-+ if (!set)
-+ return true;
-+
-+ rtx x = SET_SRC(set);
-+ if (GET_CODE(x) != PLUS)
-+ return true;
-+
-+ x = XEXP(x, 1);
-+ if (GET_CODE(x) != CONST)
-+ return true;
-+
-+ x = XEXP(x, 0);
-+ if (GET_CODE(x) != MINUS)
-+ return true;
+ ;;
+diff --git a/libgcc/config/m68k/cxxglue.c b/libgcc/config/m68k/cxxglue.c
+new file mode 100644
+index 000000000000..2a4e6374d088
+--- /dev/null
++++ libgcc/config/m68k/cxxglue.c
+@@ -0,0 +1,22 @@
++#include "stabs.h"
+
-+ x = XEXP(x, 0);
-+ if (GET_CODE(x) != NOT)
-+ return true;
++extern void __register_frame_info(void *, void *);
++extern void * _EH_FRAME_BEGINS__;
++extern void * _EH_FRAME_OBJECTS__;
+
-+ x = XEXP(x, 0);
-+ return !REG_P(x);
++void __init_eh() {
++ void ** frame = &_EH_FRAME_BEGINS__;
++ void ** object = &_EH_FRAME_OBJECTS__;
++
++ int n = *(int *)frame++;
++ int m = *(int *)object++;
++ if (n != m)
++ return;
++
++ while (n--) {
++ __register_frame_info(*frame++, *object++);
++ }
+}
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index c564c3f2db67..688f04e37ebb 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -477,3 +477,8 @@ amigaos_struct_value_rtx(tree fntype,
- rtx
- amigaos_static_chain_rtx(const_tree fntype,
- bool incoming ATTRIBUTE_UNUSED);
+
-+#undef TARGET_LEGITIMATE_COMBINED_INSN
-+#define TARGET_LEGITIMATE_COMBINED_INSN amigaos_legitimate_combined_insn
-+bool
-+amigaos_legitimate_combined_insn (rtx_insn *insn ATTRIBUTE_UNUSED);
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index d123cc065c18..ed9b76caf11d 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -4626,7 +4626,7 @@ print_operand (FILE *file, rtx op, int letter)
- /* Use `print_operand_address' instead of `output_addr_const'
- to ensure that we print relevant PIC stuff. */
- asm_fprintf (file, "%I");
-- if (TARGET_PCREL
-+ if ((TARGET_PCREL || flag_pic > 2)
- && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
- print_operand_address (file, op);
- else
-
-From dd13371d6f4ca2e66804a589b50d2bca47d58653 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 21 Aug 2017 20:27:22 +0200
-Subject: [PATCH 216/303] avoid invalid addressing modes with baserel modes
-
----
- gcc/config/m68k/m68k.md | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index d5ab0cfab8c8..c9ea341789f4 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -2468,7 +2468,7 @@
- (define_insn "*addsi3_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a")
- (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
-- (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
-+ (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLt,mSrIKLt")))]
-
-
- "! TARGET_COLDFIRE"
-
-From 7edabb7a5a3018fd8b1f410f38a31122cc0ea493 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 21 Aug 2017 20:33:59 +0200
-Subject: [PATCH 217/303] bump datestamp
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 51af5f4da01f..d77b05782e7b 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170711-124202
-+20170821-203326
-
-From 3142cd34592cdaf86c3fab9de2c674225257df8b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 31 Aug 2017 16:14:24 +0200
-Subject: [PATCH 218/303] #2 treat CLOBBERed regs as defined regs
-
----
- gcc/bbb-opts.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 99785cf5d6ad..77537a73a873 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1003,6 +1003,9 @@ insn_info::scan_rtx (rtx x)
- def |= d;
- }
- }
++ADD2INIT(__init_eh,127);
+
-+ if (code == CLOBBER)
-+ def |= use;
- }
-
- void
-
-From 821e16347528355a29fdcfd521f7cdb26414a67f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 31 Aug 2017 16:18:10 +0200
-Subject: [PATCH 219/303] also use libm020 with mcpu=68030 and higher
-
----
- gcc/config/m68k/m68kamigaos.h | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index beac496ab148..7dc0e57f5cdc 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -540,6 +540,9 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32 %{noixemul:-fl libnix} %{mcrt=nix*:-fl libnix}} " \
- "%{g:-amiga-debug-hunk} " \
- "%{mcpu=68020:-fl libm020} " \
-+ "%{mcpu=68030:-fl libm020} " \
-+ "%{mcpu=68040:-fl libm020} " \
-+ "%{mcpu=68060:-fl libm020} " \
- "%{m68020:-fl libm020} " \
- "%{mc68020:-fl libm020} " \
- "%{m68030:-fl libm020} " \
-
-From 8529c8e37e017866c4d062006a00219fd4977381 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 31 Aug 2017 16:25:52 +0200
-Subject: [PATCH 220/303] bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index d77b05782e7b..0dfee2790f53 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170821-203326
-+20170831-161819
-
-From 592ee5156864548a6d918a34001781a5a73eb51b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 11 Oct 2017 23:39:40 +0200
-Subject: [PATCH 221/303] split fpgnulib into files per function
-
----
- libgcc/config.host | 3 ++-
- libgcc/config/m68k/fpgnulib.c | 22 +++++++++++++++++
- libgcc/config/m68k/t-floatlib | 57 ++++++++++++++++++++++++++++++++++++++-----
- 3 files changed, 75 insertions(+), 7 deletions(-)
-
-diff --git a/libgcc/config.host b/libgcc/config.host
-index 5de7abdb8a95..c36e829a5025 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -817,7 +817,8 @@ m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
- m68k-*-amiga*)
-- tmake_file="$tmake_file m68k/t-glue"
-+ tmake_file="$tmake_file m68k/t-glue m68k/t-floatlib soft-fp"
-+# tmake_file="$tmake_file m68k/t-glue soft-fp"
- ;;
- m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c
-index fe41edf26aa0..9dcd5ea20397 100644
+index fe41edf26aa0..90926104d8fd 100644
--- libgcc/config/m68k/fpgnulib.c
+++ libgcc/config/m68k/fpgnulib.c
@@ -105,6 +105,7 @@ union long_double_long
@@ -35119,138 +10574,7 @@ index fe41edf26aa0..9dcd5ea20397 100644
#else /* EXTFLOAT */
-diff --git a/libgcc/config/m68k/t-floatlib b/libgcc/config/m68k/t-floatlib
-index 1ee8782d9fd2..42f6cf97ef48 100644
---- libgcc/config/m68k/t-floatlib
-+++ libgcc/config/m68k/t-floatlib
-@@ -1,10 +1,55 @@
--LIB1ASMSRC = m68k/lb1sf68.S
--LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
-- _double _float _floatex \
-- _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
-- _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
-+#
-+#LIB1ASMSRC = m68k/lb1sf68.S
-+#LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
-+# _double _float _floatex \
-+# _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
-+# _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
-+#
-
--LIB2ADD = $(srcdir)/config/m68k/fpgnulib.c xfgnulib.c
-+LIB2ADD = xfgnulib.c xfgnulib__unordsf2.c xfgnulib__unorddf2.c \
-+ xfgnulib__floatunsidf.c xfgnulib__floatsidf.c xfgnulib__floatunsisf.c \
-+ xfgnulib__floatsisf.c xfgnulib__extendsfdf2.c xfgnulib__truncdfsf2.c \
-+ xfgnulib__fixdfsi.c xfgnulib__fixsfsi.c
-+
-+xfgnulib__unordsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __UNORDSF2' > xfgnulib__unordsf2.c
-+ cat $< >> xfgnulib__unordsf2.c
-+
-+xfgnulib__unorddf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __UNORDDF2' > xfgnulib__unorddf2.c
-+ cat $< >> xfgnulib__unorddf2.c
-+
-+xfgnulib__floatunsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATUNSIDF' > xfgnulib__floatunsidf.c
-+ cat $< >> xfgnulib__floatunsidf.c
-+
-+xfgnulib__floatsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATSIDF' > xfgnulib__floatsidf.c
-+ cat $< >> xfgnulib__floatsidf.c
-+
-+xfgnulib__floatunsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATUNSISF' > xfgnulib__floatunsisf.c
-+ cat $< >> xfgnulib__floatunsisf.c
-+
-+xfgnulib__floatsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATSISF' > xfgnulib__floatsisf.c
-+ cat $< >> xfgnulib__floatsisf.c
-+
-+xfgnulib__extendsfdf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __EXTENDSFDF2' > xfgnulib__extendsfdf2.c
-+ cat $< >> xfgnulib__extendsfdf2.c
-+
-+xfgnulib__truncdfsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __TRUNCDFSF2' > xfgnulib__truncdfsf2.c
-+ cat $< >> xfgnulib__truncdfsf2.c
-+
-+xfgnulib__fixdfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FIXDFSI' > xfgnulib__fixdfsi.c
-+ cat $< >> xfgnulib__fixdfsi.c
-+
-+xfgnulib__fixsfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FIXSFSI' > xfgnulib__fixsfsi.c
-+ cat $< >> xfgnulib__fixsfsi.c
-
- xfgnulib.c: $(srcdir)/config/m68k/fpgnulib.c
- echo '#define EXTFLOAT' > xfgnulib.c
-
-From cce4b48ca8802f0c0b1ee929810a845a18285902 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 11 Oct 2017 23:40:39 +0200
-Subject: [PATCH 222/303] fix usage of return val registers for library
- functions -> always tell the return reg.
-
----
- gcc/DATESTAMP | 2 +-
- gcc/bbb-opts.c | 2 +-
- gcc/config/m68k/amigaos.c | 4 ++--
- 3 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 0dfee2790f53..c4335f1aad48 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20170831-161819
-+20171011-233828
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 77537a73a873..fe7cd79b5c7b 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -926,7 +926,7 @@ insn_info::scan ()
- rtx op, reg;
-
- if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-- for (unsigned r = REGNO(reg); r <= END_REGNO (reg); ++r)
-+ for (unsigned r = REGNO(reg); r < END_REGNO (reg); ++r)
- mark_myuse (r);
- }
- /* mark scratch registers. */
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 6aee22fa3720..53e01499341d 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -848,10 +848,10 @@ read_only_operand (rtx operand)
- rtx
- amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED)
- {
-- if (fntype && aggregate_value_p (TREE_TYPE(fntype), fntype))
-+// if (fntype && aggregate_value_p (TREE_TYPE(fntype), fntype))
- return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
-
-- return 0;
-+// return 0;
- }
-
- rtx
-
-From aea9ac0b4d8f6261006ed68ea1bb21d0f6fe57f8 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 13 Oct 2017 22:02:17 +0200
-Subject: [PATCH 223/303] further spltting of fpgnulib
-
----
- libgcc/config/m68k/fpgnulib.c | 69 +++++++++++++++-------------
- libgcc/config/m68k/t-floatlib | 102 ++++++++++++++++++++++--------------------
- 2 files changed, 91 insertions(+), 80 deletions(-)
-
-diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c
-index 9dcd5ea20397..90926104d8fd 100644
---- libgcc/config/m68k/fpgnulib.c
-+++ libgcc/config/m68k/fpgnulib.c
-@@ -418,6 +418,8 @@ float __truncdfsf2 (double);
+@@ -396,6 +418,8 @@ float __truncdfsf2 (double);
long __fixdfsi (double);
long __fixsfsi (float);
@@ -35259,7 +10583,7 @@ index 9dcd5ea20397..90926104d8fd 100644
int
__unordxf2(long double a, long double b)
{
-@@ -467,38 +469,6 @@ __extenddfxf2 (double d)
+@@ -445,38 +469,6 @@ __extenddfxf2 (double d)
return ldl.ld;
}
@@ -35298,7 +10622,7 @@ index 9dcd5ea20397..90926104d8fd 100644
/* convert a float to a long double */
long double
__extendsfxf2 (float f)
-@@ -571,6 +541,8 @@ __negxf2 (long double x1)
+@@ -549,6 +541,8 @@ __negxf2 (long double x1)
return - (double) x1;
}
@@ -35307,7 +10631,7 @@ index 9dcd5ea20397..90926104d8fd 100644
long
__cmpxf2 (long double x1, long double x2)
{
-@@ -613,5 +585,38 @@ __gexf2 (long double x1, long double x2)
+@@ -591,5 +585,38 @@ __gexf2 (long double x1, long double x2)
return __cmpdf2 ((double) x1, (double) x2);
}
@@ -35347,66 +10671,32 @@ index 9dcd5ea20397..90926104d8fd 100644
#endif /* !__mcoldfire__ */
#endif /* EXTFLOAT */
diff --git a/libgcc/config/m68k/t-floatlib b/libgcc/config/m68k/t-floatlib
-index 42f6cf97ef48..2365433a59b3 100644
+index 1ee8782d9fd2..2365433a59b3 100644
--- libgcc/config/m68k/t-floatlib
+++ libgcc/config/m68k/t-floatlib
-@@ -6,51 +6,57 @@
- # _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
- #
+@@ -1,11 +1,62 @@
+-LIB1ASMSRC = m68k/lb1sf68.S
+-LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
+- _double _float _floatex \
+- _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
+- _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
++#
++#LIB1ASMSRC = m68k/lb1sf68.S
++#LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
++# _double _float _floatex \
++# _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
++# _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
++#
--LIB2ADD = xfgnulib.c xfgnulib__unordsf2.c xfgnulib__unorddf2.c \
-- xfgnulib__floatunsidf.c xfgnulib__floatsidf.c xfgnulib__floatunsisf.c \
-- xfgnulib__floatsisf.c xfgnulib__extendsfdf2.c xfgnulib__truncdfsf2.c \
-- xfgnulib__fixdfsi.c xfgnulib__fixsfsi.c
--
--xfgnulib__unordsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __UNORDSF2' > xfgnulib__unordsf2.c
-- cat $< >> xfgnulib__unordsf2.c
--
--xfgnulib__unorddf2.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __UNORDDF2' > xfgnulib__unorddf2.c
-- cat $< >> xfgnulib__unorddf2.c
--
--xfgnulib__floatunsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __FLOATUNSIDF' > xfgnulib__floatunsidf.c
-- cat $< >> xfgnulib__floatunsidf.c
--
--xfgnulib__floatsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __FLOATSIDF' > xfgnulib__floatsidf.c
-- cat $< >> xfgnulib__floatsidf.c
--
--xfgnulib__floatunsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __FLOATUNSISF' > xfgnulib__floatunsisf.c
-- cat $< >> xfgnulib__floatunsisf.c
--
--xfgnulib__floatsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __FLOATSISF' > xfgnulib__floatsisf.c
-- cat $< >> xfgnulib__floatsisf.c
--
--xfgnulib__extendsfdf2.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __EXTENDSFDF2' > xfgnulib__extendsfdf2.c
-- cat $< >> xfgnulib__extendsfdf2.c
--
--xfgnulib__truncdfsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __TRUNCDFSF2' > xfgnulib__truncdfsf2.c
-- cat $< >> xfgnulib__truncdfsf2.c
--
--xfgnulib__fixdfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __FIXDFSI' > xfgnulib__fixdfsi.c
-- cat $< >> xfgnulib__fixdfsi.c
--
--xfgnulib__fixsfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define __FIXSFSI' > xfgnulib__fixsfsi.c
-- cat $< >> xfgnulib__fixsfsi.c
--
--xfgnulib.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define EXTFLOAT' > xfgnulib.c
-- cat $< >> xfgnulib.c
+-LIB2ADD = $(srcdir)/config/m68k/fpgnulib.c xfgnulib.c
+LIB2ADD = xfpgnulib.c xfpgnulib__unordsf2.c xfpgnulib__unorddf2.c \
+ xfpgnulib__floatunsidf.c xfpgnulib__floatsidf.c xfpgnulib__floatunsisf.c \
+ xfpgnulib__floatsisf.c xfpgnulib__extendsfdf2.c xfpgnulib__truncdfsf2.c \
+ xfpgnulib__fixdfsi.c xfpgnulib__fixsfsi.c xfpgnulib__cmpxf2.c
-+
+
+-xfgnulib.c: $(srcdir)/config/m68k/fpgnulib.c
+- echo '#define EXTFLOAT' > xfgnulib.c
+- cat $< >> xfgnulib.c
+xfpgnulib__unordsf2.c: $(srcdir)/config/m68k/fpgnulib.c
+ echo '#define __UNORDSF2' > xfpgnulib__unordsf2.c
+ cat $< >> xfpgnulib__unordsf2.c
@@ -35457,7507 +10747,345 @@ index 42f6cf97ef48..2365433a59b3 100644
+ cat $< >> xfpgnulib__cmpxf2.c
+
\ No newline at end of file
-
-From 97a50aa76b592060171013c4a00ac472d8711580 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 18 Oct 2017 19:45:35 +0200
-Subject: [PATCH 224/303] eliminating redundant loads (move.l reg,reg) is
- checking that the source value is still known
-
----
- gcc/bbb-opts.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index fe7cd79b5c7b..6e257b22266a 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3755,11 +3755,16 @@ opt_elim_dead_assign (unsigned blocked_regno)
- rtx cached_value = ii.get_track_var ()->get_values ()[ii.get_dst_regno ()];
- rtx cached_value2 = 0;
- if (cached_value && REG_P(cached_value) && REGNO(cached_value) < FIRST_PSEUDO_REGISTER)
-- cached_value2 = ii.get_track_var ()->get_values ()[REGNO(cached_value)];
-+ {
-+ cached_value2 = ii.get_track_var ()->get_values ()[REGNO(cached_value)];
-+ if (!cached_value2) // no value for the reg -> reg is invalid too
-+ cached_value = 0;
-+ }
- if (cached_value
- && (rtx_equal_p (cached_value, SET_SRC(set))
- || (cached_value2 && rtx_equal_p (cached_value2, SET_SRC(set)))))
- {
-+// fprintf(stderr, "cached_value: "); debug_rtx(cached_value);
- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
- SET_INSN_DELETED(insn);
- ++change_count;
-
-From b9e0de6883c5bcf3c58828453cc601b889a07516 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 18 Oct 2017 19:47:25 +0200
-Subject: [PATCH 225/303] bump DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index c4335f1aad48..c95c776f3dcf 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171011-233828
-+20171018-194704
-
-From 068a438a7b99afeed45bb95c08dd38ea94f0280a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 11 Nov 2017 15:01:03 +0100
-Subject: [PATCH 226/303] improved insn checking and auto inc
-
----
- gcc/bbb-opts.c | 458 ++++++++++++++++++++++++++++++++++-----------------------
- 1 file changed, 275 insertions(+), 183 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 6e257b22266a..c6aaa4dcb476 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -53,6 +53,9 @@
- */
-
- #include "config.h"
-+#define INCLUDE_VECTOR
-+#define INCLUDE_SET
-+#define INCLUDE_MAP
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-@@ -67,11 +70,6 @@
- #include "tree-pass.h"
- #include "conditions.h"
- #include "langhooks.h"
--#include <vector>
--#include <set>
--#include <map>
--
--static int xx = 0;
-
- int be_very_verbose;
- bool be_verbose;
-@@ -274,6 +272,9 @@ class insn_info
- void
- absolute2base (unsigned regno, unsigned base, rtx with_symbol);
-
-+ rtx
-+ make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool apply);
-+
- inline bool
- is_compare () const
- {
-@@ -776,7 +777,7 @@ class insn_info
- void
- scan_rtx (rtx);
-
-- void
-+ bool
- make_post_inc (int regno);
-
- void
-@@ -822,14 +823,16 @@ class insn_info
- a5_to_a7 (rtx a7);
- };
-
--void
-+bool
- insn_info::make_post_inc (int regno)
- {
-+ rtx pattern = PATTERN(insn);
-+ rtx_insn * new_insn = make_insn_raw(pattern);
-+
- // convert into POST_INC
--// debug_rtx (insn);
-- rtx set0 = single_set (insn);
-+ rtx set0 = single_set (new_insn);
- rtx set = set0;
-- SET_INSN_DELETED(insn);
-+
- if (is_compare ())
- set = SET_SRC(set);
- rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-@@ -837,21 +840,60 @@ insn_info::make_post_inc (int regno)
- mem = XEXP(mem, 1);
-
- rtx reg = XEXP(mem, 0);
-+
- XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
-
-+ if (insn_invalid_p (new_insn, 0))
-+ {
-+ XEXP(mem, 0) = reg;
-+ insn_invalid_p (insn, 0);
-+ return 0;
-+ }
-+
-+ SET_INSN_DELETED(insn);
- (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
-- insn = emit_insn_after (set0, insn);
--// debug_rtx (insn);
-+ insn = emit_insn_after (PATTERN(new_insn), insn);
-+ insn_invalid_p(insn, 0);
-+
-+ return 1;
-+}
-+
-+static rtx
-+add_clobbers (rtx_insn * oldinsn)
-+{
-+ rtx pattern = PATTERN (oldinsn);
-+ if (GET_CODE(pattern) != PARALLEL)
-+ return pattern;
-+
-+ int num_clobbers = 0;
-+ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(x) == CLOBBER)
-+ ++num_clobbers;
-+ }
-+
-+ if (!num_clobbers)
-+ return pattern;
-+
-+ rtx newpat = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (num_clobbers + 1));
-+ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(x) == CLOBBER)
-+ XVECEXP(newpat, 0, num_clobbers--) = x;
-+ }
-+
-+ XVECEXP(newpat, 0, 0) = XVECEXP(pattern, 0, 0);
-+ return newpat;
- }
-
- void
- insn_info::auto_inc_fixup (int regno, int size)
- {
- // debug_rtx (insn);
--
- rtx set0 = single_set (insn);
- rtx set = set0;
-- SET_INSN_DELETED(insn);
- if (is_compare ())
- set = SET_SRC(set);
-
-@@ -876,7 +918,7 @@ insn_info::auto_inc_fixup (int regno, int size)
- mem = XEXP(mem, 1);
-
- rtx plus = XEXP(mem, 0);
-- if ((get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) == size)
-+ if ((get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) == (unsigned) size)
- {
- XEXP(mem, 0) = XEXP(plus, 0);
- (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) = 0;
-@@ -886,8 +928,11 @@ insn_info::auto_inc_fixup (int regno, int size)
- XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)),
- (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) -= size);
- }
-- insn = emit_insn_after (set0, insn);
--// debug_rtx (insn);
-+
-+ rtx pattern = add_clobbers (insn);
-+
-+ SET_INSN_DELETED(insn);
-+ insn = emit_insn_after (pattern, insn);
- }
-
- track_var *
-@@ -1383,15 +1428,14 @@ insn_info::set_insn (rtx_insn * newinsn)
- fledder (single_set (insn));
- }
-
--void
--insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
-+rtx
-+insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool apply)
- {
- rtx set = single_set (get_insn ());
- rtx src = SET_SRC(set);
- rtx dst = SET_DEST(set);
-- bool vola = src->volatil;
-- rtx pattern;
- rtx reg = gen_raw_REG (SImode, regno);
-+ bool vola = src->volatil;
-
- if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) && !has_dst_memreg () && get_dst_symbol () == with_symbol)
- {
-@@ -1404,10 +1448,13 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- else
- dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode, offset)));
-
-- dst_mem_reg = reg;
-- dst_mem = true;
-- dst_mem_addr = offset;
-- dst_plus = offset != 0;
-+ if (apply)
-+ {
-+ dst_mem_reg = reg;
-+ dst_mem = true;
-+ dst_mem_addr = offset;
-+ dst_plus = offset != 0;
-+ }
- }
- }
-
-@@ -1438,16 +1485,27 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
- }
- }
-
-- src_mem_reg = reg;
-- src_mem = true;
-- src_mem_addr = offset;
-- src_plus = offset != 0;
-+ if (apply)
-+ {
-+ src_mem_reg = reg;
-+ src_mem = true;
-+ src_mem_addr = offset;
-+ src_plus = offset != 0;
-+ }
- }
- }
-
-- pattern = gen_rtx_SET(dst, src);
-+ rtx pattern = gen_rtx_SET(dst, src);
- src->volatil = vola;
-
-+ return pattern;
-+}
-+
-+void
-+insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
-+{
-+ rtx pattern = make_absolute2base (regno, base, with_symbol, true);
-+
- SET_INSN_DELETED(insn);
- insn = emit_insn_after (pattern, insn);
-
-@@ -1506,7 +1564,7 @@ append_reg_usage (FILE * f, rtx_insn * insn)
- if (be_very_verbose > 1)
- fprintf (f, "\n\t\t\t\t\t|%d\t", ii.get_index ());
- else
-- fprintf (f, "\n\t\t\t\t\t|\t", ii.get_index ());
-+ fprintf (f, "\n\t\t\t\t\t|\t");
- }
-
- fprintf (f, "%c ", ii.in_proepi () == IN_PROLOGUE ? 'p' : ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
-@@ -1533,6 +1591,22 @@ append_reg_usage (FILE * f, rtx_insn * insn)
-
- if (ii.is_use (FIRST_PSEUDO_REGISTER))
- fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "+cc " : " cc ");
-+ else
-+ fprintf (f, " ");
-+
-+ // append fp usage info if present
-+ if ((ii.get_use () | ii.get_def ()) & ~0xffff)
-+ {
-+ for (int j = 16; j < 24; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse (j) ? "." : " ");
-+ fprintf (f, "f%d ", j - 16);
-+ }
-+ else
-+ fprintf (f, " ");
-+ }
-
- if (f == stderr)
- fprintf (f, "\n");
-@@ -2024,7 +2098,6 @@ opt_reg_rename (void)
- if (found.find (startat) != found.end () || !infos[startat].is_use (rename_regno))
- continue;
-
--
- unsigned start = find_start (startat, rename_regno);
- // printf ("label %d <- jump %d : start %d\n", pos, startat, start); fflush (stdout);
- todo.insert (start);
-@@ -2042,7 +2115,7 @@ opt_reg_rename (void)
-
- // printf ("label start check %d use %d\n", pos, bb.is_use (rename_regno) || bb.is_def(rename_regno)); fflush (stdout);
-
-- if (bb.is_use (rename_regno) || bb.is_def(rename_regno))
-+ if (bb.is_use (rename_regno) || bb.is_def (rename_regno))
- {
- unsigned start = find_start (pos - 1, rename_regno);
- todo.insert (start);
-@@ -2136,15 +2209,14 @@ opt_reg_rename (void)
-
- for (std::set<unsigned>::iterator i = found.begin (); ok && i != found.end (); ++i)
- {
-- rtx_insn * insn = infos[*i].get_insn ();
-+ insn_info & rr = infos[*i];
-+ rtx_insn * insn = rr.get_insn ();
-
- /* temp rename. */
- temp_reg_rename (locs, PATTERN (insn), oldregno, newregno);
- if (!locs.empty ())
- {
-- int num_clobbers_to_add = 0;
-- int insn_code_number = recog (PATTERN (insn), insn, &num_clobbers_to_add);
-- if (insn_code_number < 0 || !check_asm_operands (PATTERN (insn)))
-+ if (insn_invalid_p (insn, 1))
- ok = false;
-
- /* undo temp change but keep loc and new register. */
-@@ -2160,6 +2232,12 @@ opt_reg_rename (void)
- }
-
- if (!ok)
-+ {
-+ cancel_changes (0);
-+ continue;
-+ }
-+
-+ if (!apply_change_group ())
- continue;
-
- log ("(r) opt_reg_rename %s -> %s (%d locs, start at %d)\n", reg_names[oldregno], reg_names[newregno],
-@@ -2527,18 +2605,15 @@ opt_strcpy ()
- NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
- if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2))
- {
-- int num_clobbers_to_add = 0;
-- int insn_code_number;
--
- rtx pattern = gen_rtx_SET(SET_DEST(single_set (reg2x)), SET_SRC(single_set (x2reg)));
- rtx_insn * newinsn = make_insn_raw (pattern);
-- insn_code_number = recog (PATTERN (newinsn), newinsn, &num_clobbers_to_add);
-- if (insn_code_number >= 0 && check_asm_operands (PATTERN (newinsn)))
-+
-+ if (!insn_invalid_p (newinsn, 0))
- {
- log ("(s) opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
- reg_names[REGNO(dst)]);
-
-- emit_insn_after (pattern, reg2x);
-+ emit_insn_after (newinsn, reg2x);
-
- SET_INSN_DELETED(x2reg);
- SET_INSN_DELETED(reg2x);
-@@ -2646,21 +2721,21 @@ opt_commute_add_move (void)
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
- rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(reg1dst, reg1src));
-- if (recog (PATTERN (newinsn), newinsn, 0) < 0 || !check_asm_operands (PATTERN (newinsn)))
-- continue;
-
-- if (validate_change (next, &SET_DEST(set2), newmem, 0))
-+ if (!insn_invalid_p (newinsn, 1) && validate_change (next, &SET_DEST(set2), newmem, 1) && apply_change_group ())
- {
- log ("(a) commute_add_move found\n");
-
- SET_INSN_DELETED(insn);
-
-- insn = emit_insn_before (PATTERN (newinsn), next);
-+ insn = emit_insn_before (newinsn, next);
-
- add_reg_note (next, REG_INC, reg1dst);
-
- ++change_count;
- }
-+ else
-+ cancel_changes (0);
- }
- return change_count;
- }
-@@ -2722,8 +2797,8 @@ opt_const_cmp_to_sub (void)
- lastsubval = pp.get_src_intval ();
-
- // but still check for usage after this jump
-- j2l_iterator l = jump2label.find(index + 2);
-- if (l == jump2label.end())
-+ j2l_iterator l = jump2label.find (index + 2);
-+ if (l == jump2label.end ())
- continue;
-
- insn_info & label = infos[l->second + 1];
-@@ -2785,9 +2860,7 @@ opt_const_cmp_to_sub (void)
-
- rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub));
-
-- int num_clobbers_to_add = 0;
-- int insn_code_number = recog (PATTERN (subinsn), subinsn, &num_clobbers_to_add);
-- if (insn_code_number < 0 || !check_asm_operands (PATTERN (subinsn)))
-+ if (insn_invalid_p (subinsn, 0))
- continue;
-
- /* delete move #x,dy. */
-@@ -3726,7 +3799,7 @@ track_regs ()
- * delete those insns.
- */
- static unsigned
--opt_elim_dead_assign (unsigned blocked_regno)
-+opt_elim_dead_assign (int blocked_regno)
- {
- track_regs ();
-
-@@ -3885,6 +3958,7 @@ opt_absolute (void)
-
- if (freemask && found.size () > 2)
- {
-+ unsigned regno = bit2regno (freemask);
- /* check again. */
- for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();)
- {
-@@ -3897,6 +3971,8 @@ opt_absolute (void)
- k = found.erase (k);
- else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
- k = found.erase (k);
-+ else if (insn_invalid_p (make_insn_raw (kk.make_absolute2base (regno, base, with_symbol, false)), 0))
-+ k = found.erase (k);
- else
- ++k;
- }
-@@ -3916,6 +3992,7 @@ opt_absolute (void)
- {
- insn_info & kk = infos[*k];
- kk.absolute2base (regno, base, with_symbol);
-+ insn_invalid_p (kk.get_insn (), 0);
- }
-
- // load base into reg
-@@ -3958,174 +4035,194 @@ opt_absolute (void)
- return change_count;
- }
-
--/*
-- * Convert a series of reg with offset ( (ax), 4(ax), 8(ax), ...) into autoincx ( (ax+), (ax+), (ax+), ...)
-- *
-- * 1. search a mem(reg) without offset and either src or dst is using that reg
-- * 2. follow paths until reg is dead
-- * 3. if there is another mem(reg) with offset check that
-- * a) offset fits last mode size
-- * b) all remaining insn using that reg can be updated by
-- * i) decrement the offset
-- * ii) decrement the add value
-- */
--static unsigned
--opt_autoinc ()
-+static int
-+try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- {
-- unsigned change_count = 0;
-+ int regno = REGNO(reg);
-+ unsigned size = GET_MODE_SIZE(ii.get_mode ());
-+ if (size > 4)
-+ return 0;
-
-- update_label2jump ();
-+// log ("starting auto_inc search for %s at %d\n", reg_names[regno], index);
-
-- for (unsigned index = 0; index < infos.size (); ++index)
-- {
-- insn_info & ii = infos[index];
-+ // track all fixups to modify
-+ std::set<unsigned> fixups;
-
-- if (ii.in_proepi ())
-- continue;
-+ // all paths to check
-+ std::vector<unsigned> todo;
-+ todo.push_back (index + 1);
-
-- rtx reg = 0;
-- if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 && !ii.get_src_mem_addr () && !ii.get_src_autoinc ()
-- && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-- reg = ii.get_src_mem_reg ();
-- if (!reg && ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
-- && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-- reg = ii.get_dst_mem_reg ();
-- if (!reg)
-- continue;
-+ bool match_size = false;
-+ bool ok = true;
-+ std::set<unsigned> visited;
-+ while (ok && todo.size () > 0)
-+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
-
-- int regno = REGNO(reg);
-- int size = GET_MODE_SIZE(ii.get_mode ());
-- if (size > 4)
-- continue;
-+ if (pos == index)
-+ {
-+ ok = false;
-+ break;
-+ }
-
--// log ("starting auto_inc search for %s at %d\n", reg_names[regno], index);
-+ if (visited.find (pos) != visited.end ())
-+ continue;
-+ visited.insert (pos);
-
-- // track all fixups to modify
-- std::set<unsigned> fixups;
-+ for (; pos < infos.size (); ++pos)
-+ {
-+ insn_info & jj = infos[pos];
-
-- // all paths to check
-- std::vector<unsigned> todo;
-- todo.push_back (index + 1);
-+ // check all jumps labels for register usage
-+ if (jj.is_label ())
-+ {
-+ for (l2j_iterator j = label2jump.find (jj.get_insn ()->u2.insn_uid), k = j;
-+ j != label2jump.end () && j->first == k->first; ++j)
-+ {
-+ insn_info * ll = insn2info.find (j->second)->second;
-+ if (ll->is_use (regno))
-+ {
-+ ok = false;
-+ break;
-+ }
-+ }
-+ if (ok)
-+ continue;
-+ break;
-+ }
-
-- bool match_size = false;
-- bool ok = true;
-- std::set<unsigned> visited;
-- while (ok && todo.size () > 0)
-- {
-- unsigned pos = todo[todo.size () - 1];
-- todo.pop_back ();
-+ // break if no longer used
-+ if (!jj.is_use (regno))
-+ break;
-
-- if (pos == index)
-+ if (jj.in_proepi ())
- {
- ok = false;
- break;
- }
-
-- if (visited.find (pos) != visited.end ())
-+ // add all labels
-+ if (jj.is_jump ())
-+ {
-+ for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end () && j->first == k->first; ++j)
-+ todo.push_back (j->second);
-+ continue;
-+ }
-+
-+ // not used directly
-+ if (!jj.is_myuse (regno))
- continue;
-- visited.insert (pos);
-
-- for (; pos < infos.size (); ++pos)
-+ // can't fixup such kind of insn (yet)
-+ if (single_set (jj.get_insn ()) == 0)
- {
-- insn_info & jj = infos[pos];
-+ ok = false;
-+ break;
-+ }
-
-- // check all jumps labels for register usage
-- if (jj.is_label ())
-+ // if reg is src reg, op must be add and addend must be large enough
-+ if (jj.get_src_regno () == regno || jj.get_src_mem_regno () == regno)
-+ {
-+ if (jj.get_src_intval () < (int) size || (jj.get_dst_mem_regno () == regno && jj.get_dst_addr () < size))
- {
-- for (l2j_iterator j = label2jump.find (jj.get_insn ()->u2.insn_uid), k = j;
-- j != label2jump.end () && j->first == k->first; ++j)
-- {
-- insn_info * ll = insn2info.find (j->second)->second;
-- if (ll->is_use (regno))
-- {
-- ok = false;
-- break;
-- }
-- }
-- if (ok)
-- continue;
-+ ok = false;
- break;
- }
-
-- // break if no longer used
-- if (!jj.is_use (regno))
-- break;
-+ if (jj.get_dst_addr () == size)
-+ match_size = true;
-
-- if (jj.in_proepi ())
-+ fixups.insert (pos);
-+ }
-+ else if (jj.get_dst_mem_regno () == regno)
-+ {
-+ if (jj.get_dst_addr () < size)
- {
- ok = false;
- break;
- }
-
-- // add all labels
-- if (jj.is_jump ())
-- {
-- for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end () && j->first == k->first;
-- ++j)
-- todo.push_back (j->second);
-- continue;
-- }
-+ if (jj.get_dst_addr () == size)
-+ match_size = true;
-
-- // not used directly
-- if (!jj.is_myuse (regno))
-- continue;
-+ fixups.insert (pos);
-+ }
-+ else
-+ {
-+ ok = false;
-+ break;
-+ }
-
-- // if reg is src reg, op must be add and addend must be large enough
-- if (jj.get_src_regno () == regno || jj.get_src_mem_regno () == regno)
-- {
-- if (jj.get_src_intval () < size || (jj.get_dst_mem_regno () == regno && jj.get_dst_addr () < size))
-- {
-- ok = false;
-- break;
-- }
-+ // done if this is an add
-+ if (ii.is_def (regno))
-+ break;
-+ }
-+ }
-
-- if (jj.get_dst_addr () == size)
-- match_size = true;
-+ if (!ok || !match_size || !fixups.size ())
-+ return 0;;
-
-- fixups.insert (pos);
-- }
-- else if (jj.get_dst_mem_regno () == regno)
-- {
-- if (jj.get_dst_addr () < size)
-- {
-- ok = false;
-- break;
-- }
-+ if (!ii.make_post_inc (regno))
-+ return 0;
-
-- if (jj.get_dst_addr () == size)
-- match_size = true;
-+ log ("(i) auto_inc for %s at %d\n", reg_names[regno], index);
-
-- fixups.insert (pos);
-- }
-- else
-- {
-- ok = false;
-- break;
-- }
-+ // fix all offsets / adds
-+ for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
-+ {
-+// log ("(i) fixup at %d\n", *k);
-+ insn_info & kk = infos[*k];
-+ kk.auto_inc_fixup (regno, size);
-+ }
-+ return 1;
-+}
-
-- // done if this is an add
-- if (ii.is_def (regno))
-- break;
-- }
-- }
-+/*
-+ * Convert a series of reg with offset ( (ax), 4(ax), 8(ax), ...) into autoincx ( (ax+), (ax+), (ax+), ...)
-+ *
-+ * 1. search a mem(reg) without offset and either src or dst is using that reg
-+ * 2. follow paths until reg is dead
-+ * 3. if there is another mem(reg) with offset check that
-+ * a) offset fits last mode size
-+ * b) all remaining insn using that reg can be updated by
-+ * i) decrement the offset
-+ * ii) decrement the add value
-+ */
-+static unsigned
-+opt_autoinc ()
-+{
-+ unsigned change_count = 0;
-+
-+ update_label2jump ();
-+
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ if (ii.in_proepi ())
-+ continue;
-
-- if (!ok || !match_size || !fixups.size ())
-+ if (!INSN_P(ii.get_insn ()))
- continue;
-
-- log ("(i) auto_inc for %s at %d\n", reg_names[regno], index);
-+// // more than one reg used
-+// if (ii.get_myuse () & (ii.get_myuse () - 1))
-+// continue;
-
-- ii.make_post_inc (regno);
-+// // don't if fp regs are touched
-+// if ((ii.get_myuse () & 0xff0000))
-+// continue;
-
-- // fix all offsets / adds
-- for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
-- {
--// log ("(i) fixup at %d\n", *k);
-- insn_info & kk = infos[*k];
-- kk.auto_inc_fixup (regno, size);
-- }
-+ rtx reg = 0;
-+ if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 && !ii.get_src_mem_addr () && !ii.get_src_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-+ change_count += try_auto_inc (index, ii, ii.get_src_mem_reg ());
-+
-+ if (!reg && ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-+ change_count += try_auto_inc (index, ii, ii.get_dst_mem_reg ());
-
-- ++change_count;
-- --index; // rerun insn to check src and dst
- }
-
- return change_count;
-@@ -4207,11 +4304,6 @@ namespace
- bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
- bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
-
--// ++xx;
--// printf ("x: %d\n", xx);
--// if (xx <= 48 || xx > 54)
--// do_autoinc = false;
--
- if (be_very_verbose)
- log ("ENTER\n");
-
-
-From 5c2dd1b12baffbf3e34da07e5fec09452f251d9e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 12 Nov 2017 18:43:05 +0100
-Subject: [PATCH 227/303] autoinc improved, new register tracking is incorrect
-
----
- gcc/bbb-opts.c | 308 +++++++++++++++++++++++++++------------------------------
- 1 file changed, 145 insertions(+), 163 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index c6aaa4dcb476..55cfae075f36 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -118,69 +118,72 @@ enum proepis
-
- class track_var
- {
-+ unsigned * indexes;
- rtx * values;
- unsigned * versions;
-
- public:
- track_var (track_var const * o = 0) :
-- values ((rtx *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(rtx))), versions (
-+ indexes ((unsigned *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(unsigned))), values (
-+ (rtx *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(rtx))), versions (
- (unsigned *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(unsigned)))
- {
- if (o)
- assign (o);
- }
-
-- rtx *
-- get_values () const
-+ void
-+ set (unsigned regno, unsigned index, rtx rtx, unsigned ver)
- {
-- return values;
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return;
-+
-+ indexes[regno] = index;
-+ values[regno] = rtx;
-+ versions[regno] = ver;
- }
-
-- void
-- set_version (unsigned regno, unsigned ver)
-- {
-- if (regno < FIRST_PSEUDO_REGISTER)
-- versions[regno] = ver;
-+ unsigned get_index(unsigned regno) const {
-+ return indexes[regno];
-+ }
+diff --git a/libgcc/config/m68k/t-glue b/libgcc/config/m68k/t-glue
+new file mode 100644
+index 000000000000..09cf7b47911c
+--- /dev/null
++++ libgcc/config/m68k/t-glue
+@@ -0,0 +1,5 @@
++cxxglue.o: $(srcdir)/config/m68k/cxxglue.c
++ $(CC) $(CFLAGS) -c $< -noixemul
+
-+ rtx get_value(unsigned regno) const {
-+ return values[regno];
-+ }
++EXTRA_PARTS=cxxglue.o
+
-+ unsigned get_version(unsigned regno) const {
-+ return versions[regno];
- }
-
- void
- assign (track_var const * o) const
- {
-+ memcpy (indexes, o->indexes, FIRST_PSEUDO_REGISTER * sizeof(unsigned));
- memcpy (values, o->values, FIRST_PSEUDO_REGISTER * sizeof(rtx));
- memcpy (versions, o->versions, FIRST_PSEUDO_REGISTER * sizeof(unsigned));
- }
-
- /* only keep common values in both sides. */
- void
-- merge (track_var * o)
-+ merge (track_var * o, unsigned at)
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (values[i] && o->values[i] && rtx_equal_p (values[i], o->values[i]))
-- {
-- int code = GET_CODE(values[i]);
-- if (code != CONST_INT && code != CONST_FIXED && code != CONST_DOUBLE && versions[i] != o->versions[i])
-- values[i] = o->values[i] = 0;
-- }
-- else
-+ indexes[i] = at;
-+ if (versions[i] != o->versions[0] || !values[i] || !o->values[i] || !rtx_equal_p (values[i], o->values[i]))
- values[i] = o->values[i] = 0;
- }
- }
-
- /* true if a merge would not change anything. */
- bool
-- contains (track_var const * o) const
-+ no_merge_needed (track_var const * o) const
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (values[i] && o->values[i] && rtx_equal_p (values[i], o->values[i]))
-- {
-- int code = GET_CODE(values[i]);
-- if (code != CONST_INT && code != CONST_FIXED && code != CONST_DOUBLE && versions[i] != o->versions[i])
-- return false;
-- }
-- else if (values[i])
-- return false;
-+ if (versions[i] != o->versions[0] || !values[i] || !o->values[i] || !rtx_equal_p (values[i], o->values[i]))
-+ if (values[i])
-+ return false;
- }
- return true;
- }
-@@ -365,7 +368,7 @@ class insn_info
- }
-
- inline unsigned
-- get_dst_addr () const
-+ get_dst_mem_addr () const
- {
- return dst_mem_addr;
- }
-@@ -826,8 +829,8 @@ class insn_info
- bool
- insn_info::make_post_inc (int regno)
- {
-- rtx pattern = PATTERN(insn);
-- rtx_insn * new_insn = make_insn_raw(pattern);
-+ rtx pattern = PATTERN (insn);
-+ rtx_insn * new_insn = make_insn_raw (pattern);
-
- // convert into POST_INC
- rtx set0 = single_set (new_insn);
-@@ -852,8 +855,8 @@ insn_info::make_post_inc (int regno)
-
- SET_INSN_DELETED(insn);
- (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
-- insn = emit_insn_after (PATTERN(new_insn), insn);
-- insn_invalid_p(insn, 0);
-+ insn = emit_insn_after (PATTERN (new_insn), insn);
-+ insn_invalid_p (insn, 0);
-
- return 1;
- }
-@@ -1010,11 +1013,15 @@ insn_info::scan_rtx (rtx x)
- unsigned u = use;
- unsigned mu = myuse;
- use = myuse = 0;
-- scan_rtx (SET_DEST(x));
-- if (REG_P(SET_DEST(x)))
-+ rtx dst = SET_DEST(x);
-+ scan_rtx (dst);
-+ if (REG_P(dst) || ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG) && REG_P(XEXP(dst, 0))))
- {
- def |= use;
-- use = u;
-+ if ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG))
-+ use |= u;
-+ else
-+ use = u;
- myuse = mu;
- }
- scan_rtx (SET_SRC(x));
-@@ -1439,7 +1446,7 @@ insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, b
-
- if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) && !has_dst_memreg () && get_dst_symbol () == with_symbol)
- {
-- unsigned addr = get_dst_addr ();
-+ unsigned addr = get_dst_mem_addr ();
- unsigned offset = addr - base;
- if (offset <= 0x7ffe)
- {
-@@ -3591,7 +3598,55 @@ opt_shrink_stack_frame (void)
- return changed;
+diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
+index 1fb6026d123f..7bf0e4236f64 100644
+--- libgcc/unwind-dw2.c
++++ libgcc/unwind-dw2.c
+@@ -260,6 +260,9 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
}
--/* Update the insn_infos to 'know' the value for each register. */
-+/* Update the insn_infos to 'know' the value for each register.
-+ *
-+ * atm only assignments to registers are optimized.
-+ *
-+ * We track register aliases:
-+ *
-+ * ;10
-+ * move.l 4(a0),d0
-+ *
-+ * ;15
-+ * move.l d0,d1
-+ *
-+ *
-+ * ;18
-+ * move.l d1,d2
-+ *
-+ * - results into d0 is an alias for d1 (and vice versa).
-+ * - to identify if a register is still changed, we also track the line where it was assigned.
-+ * - in addition to register aliases memory reads are tracked too for normal memory access (e.g. no auto inc)
-+ * but not if the memory read is marked as volatile
-+ *
-+ * E.g.
-+ *
-+ * d0[10]: 4(a0)[10]
-+ * d1[15]: d0[10]
-+ * d2[18]: d1[15]
-+ *
-+ * with that information we know that d2[18] also contains 4(a0)[10]
-+ *
-+ * info to track per register:
-+ * line index where the value was assigned
-+ * rtx which was assigned - or null if not a usable rtx
-+ * reg line index - if rtx is a register
-+ *
-+ * for each assignment which is not to a register the rtx are scanned and set to null on match
-+ *
-+ * on jumps the current state is duplicated and merged at the given label
-+ *
-+ * on merge only identical info is kept, rest is discarded
-+ *
-+ * for each insn first the track info for all defined regs is discarded before the new one is set.
-+ *
-+ *
-+ * after the track info is complete, each insn is evaluated agains the track info.
-+ *
-+ * now redundant loads are found and eliminated
-+ * also unused assignments are found an eliminated
-+ *
-+ */
- static unsigned
- track_regs ()
- {
-@@ -3615,47 +3670,21 @@ track_regs ()
- track_var * const track = todo.begin ()->second;
- todo.erase (todo.begin ());
-
-- rtx * values = track->get_values ();
-- // track register aliases: know which register is used in what slot
-- // if a register changes, invalidate each slot
-- std::multimap<unsigned, unsigned> reg2slot;
-- for (unsigned slot = 0; slot < FIRST_PSEUDO_REGISTER; ++slot)
-- if (values[slot])
-- {
-- insn_info vv;
-- vv.scan_rtx (values[slot]);
-- for (unsigned regno = 0, m = vv.get_myuse (); m; ++regno, m >>= 1)
-- if (m & 1)
-- reg2slot.insert (std::make_pair (regno, slot));
-- }
--
-- unsigned version = startpos;
-
- for (unsigned index = startpos; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-
- // already visited?
-- if (index != startpos && ii.is_visited () && ii.get_track_var ()->contains (track))
-+ if (index != startpos && ii.is_visited () && ii.get_track_var ()->no_merge_needed(track))
- break;
-
- // only keep common values at labels
- if (ii.is_label ())
- {
-- version = index;
- if (ii.is_visited ())
- {
-- ii.get_track_var ()->merge (track);
-- reg2slot.clear ();
-- for (unsigned slot = 0; slot < FIRST_PSEUDO_REGISTER; ++slot)
-- if (values[slot])
-- {
-- insn_info vv;
-- vv.scan_rtx (values[slot]);
-- for (unsigned regno = 0, m = vv.get_myuse (); m; ++regno, m >>= 1)
-- if (m & 1)
-- reg2slot.insert (std::make_pair (regno, slot));
-- }
-+ ii.get_track_var ()->merge (track, index);
- }
- else
- {
-@@ -3675,18 +3704,11 @@ track_regs ()
- unsigned def = ii.get_def ();
- if (def)
- {
-- for (int regno = 0; regno < 16; ++regno)
-- if ((1 << regno) & def)
-- {
-- values[regno] = 0;
-- // invalidate all referring registers
-- for (std::multimap<unsigned, unsigned>::iterator j = reg2slot.find (regno), k = j;
-- j != reg2slot.end () && j->first == k->first;)
-- {
-- values[j->second] = 0;
-- j = reg2slot.erase (j);
-- }
-- }
-+ for (int regno = 0; regno < 24; ++regno)
-+ {
-+ if ((1 << regno) & def)
-+ track->set(regno, index, 0, index);
-+ }
- }
-
- if (ii.is_call ())
-@@ -3704,90 +3726,53 @@ track_regs ()
- todo.insert (std::make_pair (i->second, new track_var (track)));
-
- if (set && GET_CODE(SET_SRC(set)) == IF_THEN_ELSE)
-- {
-- version = index;
- continue;
-- }
-
- // unconditional jump
- break;
- }
-
-- if (!set)
-+ if (!set || !ii.get_def ())
- continue;
-
-- rtx src, dest;
-- if (ii.get_src_autoinc ())
-- {
-- int regno = ii.get_src_mem_regno ();
-- values[regno] = 0;
-- for (std::multimap<unsigned, unsigned>::iterator j = reg2slot.find (regno), k = j;
-- j != reg2slot.end () && j->first == k->first;)
-- {
-- values[j->second] = 0;
-- j = reg2slot.erase (j);
-- }
-- }
--
-- if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) & ii.get_myuse ()))
-- src = 0;
-- else
-- {
-- src = SET_SRC(set);
-- if (ii.is_src_mem () && src->volatil)
-- src = 0;
-- }
--
-- if (ii.get_dst_autoinc ())
-+ // invalidate all which are using the value from dest since that value changed
-+ rtx dst = SET_DEST(set);
-+ if (MEM_P(dst))
- {
-- int regno = ii.get_dst_mem_regno ();
-- values[regno] = 0;
-- for (std::multimap<unsigned, unsigned>::iterator j = reg2slot.find (regno), k = j;
-- j != reg2slot.end () && j->first == k->first;)
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- values[j->second] = 0;
-- j = reg2slot.erase (j);
-+ if (rtx_equal_p(dst, track->get_value(i)))
-+ track->set(i, index, 0, index);
- }
- }
-
-- if (src == 0 || ii.get_src_op () || ii.get_dst_autoinc ())
-- dest = 0;
-- else
-- dest = SET_DEST(set);
--
-- // track register values for now
- int dregno = ii.get_dst_regno ();
-- int sregno = ii.get_src_regno ();
-+ if (dregno < 0)
-+ continue;
-
-- // track reg2slot
-- if (dregno >= 0)
-- {
-- for (unsigned regno = 0, m = ii.get_myuse (); m; ++regno, m >>= 1)
-- if (m & 1)
-- reg2slot.insert (std::make_pair (regno, dregno));
-+ // operation, autoinf or more than one register used: can't cache
-+ if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) & ii.get_myuse ()))
-+ continue;
-
-- if (sregno >= 0)
-- {
-- reg2slot.insert (std::make_pair (dregno, sregno));
-- reg2slot.insert (std::make_pair (sregno, dregno));
-- }
-- }
-+ rtx src = SET_SRC(set);
-+ if (ii.is_src_mem () && src->volatil)
-+ continue;
-
-- if (sregno >= 0)
-+ // add the entry - determine the version - use 0 for const values
-+ unsigned version;
-+ if (GET_CODE(src) != CONST_INT && GET_CODE(src) != CONST_FIXED && GET_CODE(src) != CONST_DOUBLE)
- {
-- values[sregno] = dest;
-- track->set_version (sregno, version);
-- for (unsigned i = sregno + 1; i < END_REGNO (ii.get_src_reg ()); ++i)
-- values[i] = 0;
-+ if (ii.get_src_regno() >= 0)
-+ version = track->get_index(ii.get_src_regno());
-+ else if (ii.get_src_mem_regno() >= 0)
-+ version = track->get_index(ii.get_src_mem_regno());
-+ else
-+ version = index;
- }
-+ else
-+ version = 0;
-
-- if (dregno >= 0)
-- {
-- values[dregno] = src;
-- track->set_version (dregno, version);
-- for (unsigned i = dregno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i)
-- values[i] = 0;
-- }
-+ track->set(dregno, index, src, version);
- }
- delete track;
- }
-@@ -3822,26 +3807,23 @@ opt_elim_dead_assign (int blocked_regno)
- ++change_count;
- continue;
- }
-+
-+ // check for redundant load
- if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno
- && !ii.is_use (ii.get_dst_regno ()))
- {
-- rtx cached_value = ii.get_track_var ()->get_values ()[ii.get_dst_regno ()];
-- rtx cached_value2 = 0;
-- if (cached_value && REG_P(cached_value) && REGNO(cached_value) < FIRST_PSEUDO_REGISTER)
-- {
-- cached_value2 = ii.get_track_var ()->get_values ()[REGNO(cached_value)];
-- if (!cached_value2) // no value for the reg -> reg is invalid too
-- cached_value = 0;
-- }
-- if (cached_value
-- && (rtx_equal_p (cached_value, SET_SRC(set))
-- || (cached_value2 && rtx_equal_p (cached_value2, SET_SRC(set)))))
-+ track_var * track = ii.get_track_var();
-+ rtx src = SET_SRC(set);
-+ if (rtx_equal_p(track->get_value(ii.get_dst_regno()), src))
- {
--// fprintf(stderr, "cached_value: "); debug_rtx(cached_value);
-- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-- SET_INSN_DELETED(insn);
-- ++change_count;
-- continue;
-+ if ((REG_P(src) && track->get_version(ii.get_dst_regno()) == track->get_index(REGNO(src)))
-+ || !REG_P(src))
-+ {
-+ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
- }
- }
- }
-@@ -3883,7 +3865,7 @@ opt_absolute (void)
-
- std::vector<unsigned> found;
- found.push_back (i);
-- int base = ii.get_dst_addr ();
-+ int base = ii.get_dst_mem_addr ();
- int max = base;
- unsigned j = i + 1;
- for (; j < infos.size (); ++j)
-@@ -3916,7 +3898,7 @@ opt_absolute (void)
-
- if (j_dst)
- {
-- int addr = jj.get_dst_addr ();
-+ int addr = jj.get_dst_mem_addr ();
- if (addr < base)
- {
- if (max - addr <= 0x7ffe)
-@@ -3967,7 +3949,7 @@ opt_absolute (void)
- && kk.get_dst_symbol () == with_symbol;
- bool k_src = kk.is_src_mem () && (kk.has_src_addr () || kk.get_src_symbol ()) && !kk.has_src_memreg ()
- && kk.get_src_symbol () == with_symbol;
-- if (k_dst && kk.get_dst_addr () - base > 0x7ffc)
-+ if (k_dst && kk.get_dst_mem_addr () - base > 0x7ffc)
- k = found.erase (k);
- else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
- k = found.erase (k);
-@@ -4124,26 +4106,26 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- // if reg is src reg, op must be add and addend must be large enough
- if (jj.get_src_regno () == regno || jj.get_src_mem_regno () == regno)
- {
-- if (jj.get_src_intval () < (int) size || (jj.get_dst_mem_regno () == regno && jj.get_dst_addr () < size))
-+ if (jj.get_src_mem_addr () < size || (jj.get_dst_mem_regno () == regno && jj.get_dst_mem_addr () < size))
- {
- ok = false;
- break;
- }
-
-- if (jj.get_dst_addr () == size)
-+ if (jj.get_src_mem_addr () == size)
- match_size = true;
-
- fixups.insert (pos);
- }
- else if (jj.get_dst_mem_regno () == regno)
- {
-- if (jj.get_dst_addr () < size)
-+ if (jj.get_dst_mem_addr () < size)
- {
- ok = false;
- break;
- }
-
-- if (jj.get_dst_addr () == size)
-+ if (jj.get_dst_mem_addr () == size)
- match_size = true;
-
- fixups.insert (pos);
-
-From aa0ae94cf14aa246fb5f1907a086615e39278b3a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 13 Nov 2017 22:20:19 +0100
-Subject: [PATCH 228/303] improved opt_autoinc() plus some bug fixes
-
----
- gcc/bbb-opts.c | 38 +++++++++++++++++++++-----------------
- 1 file changed, 21 insertions(+), 17 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index c6aaa4dcb476..20126991e5d2 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -365,7 +365,7 @@ class insn_info
- }
-
- inline unsigned
-- get_dst_addr () const
-+ get_dst_mem_addr () const
- {
- return dst_mem_addr;
- }
-@@ -1010,10 +1010,14 @@ insn_info::scan_rtx (rtx x)
- unsigned u = use;
- unsigned mu = myuse;
- use = myuse = 0;
-- scan_rtx (SET_DEST(x));
-- if (REG_P(SET_DEST(x)))
-+ rtx dst = SET_DEST(x);
-+ scan_rtx (dst);
-+ if (REG_P(dst) || ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG) && REG_P(XEXP(dst, 0))))
- {
- def |= use;
-+ if ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG))
-+ use |= u;
-+ else
- use = u;
- myuse = mu;
- }
-@@ -1439,7 +1443,7 @@ insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, b
-
- if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) && !has_dst_memreg () && get_dst_symbol () == with_symbol)
- {
-- unsigned addr = get_dst_addr ();
-+ unsigned addr = get_dst_mem_addr ();
- unsigned offset = addr - base;
- if (offset <= 0x7ffe)
- {
-@@ -3883,7 +3887,7 @@ opt_absolute (void)
-
- std::vector<unsigned> found;
- found.push_back (i);
-- int base = ii.get_dst_addr ();
-+ int base = ii.get_dst_mem_addr ();
- int max = base;
- unsigned j = i + 1;
- for (; j < infos.size (); ++j)
-@@ -3916,7 +3920,7 @@ opt_absolute (void)
-
- if (j_dst)
- {
-- int addr = jj.get_dst_addr ();
-+ int addr = jj.get_dst_mem_addr ();
- if (addr < base)
- {
- if (max - addr <= 0x7ffe)
-@@ -3967,7 +3971,7 @@ opt_absolute (void)
- && kk.get_dst_symbol () == with_symbol;
- bool k_src = kk.is_src_mem () && (kk.has_src_addr () || kk.get_src_symbol ()) && !kk.has_src_memreg ()
- && kk.get_src_symbol () == with_symbol;
-- if (k_dst && kk.get_dst_addr () - base > 0x7ffc)
-+ if (k_dst && kk.get_dst_mem_addr () - base > 0x7ffc)
- k = found.erase (k);
- else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
- k = found.erase (k);
-@@ -4124,26 +4128,26 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- // if reg is src reg, op must be add and addend must be large enough
- if (jj.get_src_regno () == regno || jj.get_src_mem_regno () == regno)
- {
-- if (jj.get_src_intval () < (int) size || (jj.get_dst_mem_regno () == regno && jj.get_dst_addr () < size))
-+ if (jj.get_src_mem_addr () < size || (jj.get_dst_mem_regno () == regno && jj.get_dst_mem_addr () < size))
- {
- ok = false;
- break;
- }
-
-- if (jj.get_dst_addr () == size)
-+ if (jj.get_src_mem_addr () == size)
- match_size = true;
-
- fixups.insert (pos);
- }
- else if (jj.get_dst_mem_regno () == regno)
- {
-- if (jj.get_dst_addr () < size)
-+ if (jj.get_dst_mem_addr () < size)
- {
- ok = false;
- break;
- }
-
-- if (jj.get_dst_addr () == size)
-+ if (jj.get_dst_mem_addr () == size)
- match_size = true;
-
- fixups.insert (pos);
-@@ -4216,7 +4220,7 @@ opt_autoinc ()
-
- rtx reg = 0;
- if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 && !ii.get_src_mem_addr () && !ii.get_src_autoinc ()
-- && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () && ii.get_src_mem_regno () != ii.get_dst_regno ())
- change_count += try_auto_inc (index, ii, ii.get_src_mem_reg ());
-
- if (!reg && ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
-@@ -4293,16 +4297,16 @@ namespace
- if (be_very_verbose)
- be_verbose = true;
-
-- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-- bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr (string_bbb_opts, '+');
-+ bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
- bool do_const_cmp_to_sub = strchr (string_bbb_opts, 'c') || strchr (string_bbb_opts, '+');
-- bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr (string_bbb_opts, '+');
- bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr (string_bbb_opts, '+');
-- bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
- bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
-- bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
- bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
-+ bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr (string_bbb_opts, '+');
-+ bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr (string_bbb_opts, '+');
-+ bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
-+ bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
-
- if (be_very_verbose)
- log ("ENTER\n");
-
-From 7a4225792c22aaab94d962e6890fb0deaddfd015 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 10:36:18 +0100
-Subject: [PATCH 229/303] fix possible stack corruption if sp is used in
- assignments
-
----
- gcc/bbb-opts.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 20126991e5d2..d9b89c6e29ac 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2993,12 +2993,17 @@ opt_merge_add (void)
- static unsigned
- track_sp ()
- {
--// reset visited flags
-+// reset visited flags - also check if sp is used as REG src.
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
- ii.clear_visited ();
- ii.set_sp_offset (0);
-+
-+ // if sp is used as source, we cannot shrink the stack yet
-+ // too complicated
-+ if (ii.get_src_regno() == STACK_POINTER_REGNUM)
-+ return -1;
- }
+ /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
++#ifdef TARGET_AMIGA
++static int overregs[16];
++#endif
- // add entry point
-
-From 0ef223ac20734c9b1998f62b6bef5f04d9cbf789 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 10:37:11 +0100
-Subject: [PATCH 230/303] update target-help to be complete and better readable
-
----
- gcc/config/m68k/amigaos.opt | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 9c08ba43196e..770cff6a4bd5 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -45,4 +45,19 @@ Specify startup binary
+ inline void
+ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
+@@ -271,6 +274,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
+ gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
+ size = dwarf_reg_size_table[index];
- fbbb=
- Target RejectNegative Report Var(string_bbb_opts) Joined
---fbbb=\t\tEnable Bebbo's optimizations. Default: -fbbb=+\n valid letters:\n\t\t+\t\tenable all\n\t\t-\t\tdisable all\n\t\ta\t\tadd move optimization\n\t\tc\t\tcompare to sub\n\t\te\t\teliminate dead assignments\n\t\tf\t\tshrink stack frame\n\t\tm\t\tmerge add statements\n\t\tp\t\tpropagate move pairs from loops\n\t\tr\t\tadditional reg rename pass\n\t\tv\t\tbe verbose\n\t\tx or X\t\tdump insns
-+-fbbb=Enable Bebbo's optimizations. \
-++ enable all optimizations \
-+a commute add move instructions \
-+b use register for base addresses \
-+c convert load const and compare into a sub \
-+e eliminate dead assignments + redundant loads \
-+f shrink stack frame \
-+i use post increment on addresses \
-+m merge add and move statements \
-+p propagate move assignment pairs out of loops \
-+r register renaming to maybe save registers \
-+s a strcpy optimization \
-+v be verbose \
-+V be very verbose \
-+x dump insns \
-+Default: -fbbb=+
-
-From 09c4f1cf165378985667aa9a82c1fa0403e60dd2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 10:49:16 +0100
-Subject: [PATCH 231/303] merge from devel1
-
----
- gcc/bbb-opts.c | 19 ++++++++++++-------
- 1 file changed, 12 insertions(+), 7 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 55cfae075f36..47902cea4658 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2996,12 +2996,17 @@ opt_merge_add (void)
- static unsigned
- track_sp ()
- {
--// reset visited flags
-+// reset visited flags - also check if sp is used as REG src.
- for (unsigned index = 0; index < infos.size (); ++index)
++#ifdef TARGET_AMIGA
++ overregs[index] = val;
++#endif
+ if (_Unwind_IsExtendedContext (context) && context->by_value[index])
{
- insn_info & ii = infos[index];
- ii.clear_visited ();
- ii.set_sp_offset (0);
-+
-+ // if sp is used as source, we cannot shrink the stack yet
-+ // too complicated
-+ if (ii.get_src_regno() == STACK_POINTER_REGNUM)
-+ return -1;
- }
-
- // add entry point
-@@ -4198,7 +4203,7 @@ opt_autoinc ()
-
- rtx reg = 0;
- if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 && !ii.get_src_mem_addr () && !ii.get_src_autoinc ()
-- && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () && ii.get_src_mem_regno () != ii.get_dst_regno ())
- change_count += try_auto_inc (index, ii, ii.get_src_mem_reg ());
-
- if (!reg && ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
-@@ -4275,16 +4280,16 @@ namespace
- if (be_very_verbose)
- be_verbose = true;
-
-- bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
- bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr (string_bbb_opts, '+');
-- bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr (string_bbb_opts, '+');
-+ bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
- bool do_const_cmp_to_sub = strchr (string_bbb_opts, 'c') || strchr (string_bbb_opts, '+');
-- bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr (string_bbb_opts, '+');
- bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr (string_bbb_opts, '+');
-- bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
- bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr (string_bbb_opts, '+');
-- bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts, '+');
- bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts, '+');
-+ bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr (string_bbb_opts, '+');
-+ bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr (string_bbb_opts, '+');
-+ bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr (string_bbb_opts, '+');
-+ bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr (string_bbb_opts, '+');
-
- if (be_very_verbose)
- log ("ENTER\n");
-
-From 3d8120f2ca2cedeba1b42ece6e7c75f216324614 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 11:11:17 +0100
-Subject: [PATCH 232/303] beautify target-help
-
----
- gcc/config/m68k/amigaos.opt | 30 +++++++++++++++---------------
- 1 file changed, 15 insertions(+), 15 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 770cff6a4bd5..d87f884f06b3 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -45,19 +45,19 @@ Specify startup binary
-
- fbbb=
- Target RejectNegative Report Var(string_bbb_opts) Joined
---fbbb=Enable Bebbo's optimizations. \
--+ enable all optimizations \
--a commute add move instructions \
--b use register for base addresses \
--c convert load const and compare into a sub \
--e eliminate dead assignments + redundant loads \
--f shrink stack frame \
--i use post increment on addresses \
--m merge add and move statements \
--p propagate move assignment pairs out of loops \
--r register renaming to maybe save registers \
--s a strcpy optimization \
--v be verbose \
--V be very verbose \
--x dump insns \
-+-fbbb=Enable Bebbo's optimizations.
-++ enable all optimizations
-+a commute add move instructions
-+b use register for base addresses
-+c convert load const and compare into a sub
-+e eliminate dead assignments + redundant loads
-+f shrink stack frame
-+i use post increment on addresses
-+m merge add and move statements
-+p propagate move assignment pairs out of loops
-+r register renaming to maybe save registers
-+s a strcpy optimization
-+v be verbose
-+V be very verbose
-+x dump insns
- Default: -fbbb=+
-
-From 3227e2247242531bd11713c4d6d12cec096196bc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 17:21:21 +0100
-Subject: [PATCH 233/303] reworked register tracking seems to work
-
----
- gcc/bbb-opts.c | 21 +++++++--------------
- 1 file changed, 7 insertions(+), 14 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 47902cea4658..f971c402cf84 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -3706,14 +3706,19 @@ track_regs ()
- if (ii.is_compare ())
- continue;
-
-+ int dregno = ii.get_dst_regno ();
- unsigned def = ii.get_def ();
- if (def)
- {
-- for (int regno = 0; regno < 24; ++regno)
-+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
- {
-- if ((1 << regno) & def)
-+ // register changed or used somehow
-+ if ( ((1 << regno) & def) || (infos[track->get_index(regno)].get_myuse() & def))
- track->set(regno, index, 0, index);
- }
-+ // clear on self update
-+ if (def & ii.get_myuse())
-+ track->set(dregno, index, 0, index);
- }
-
- if (ii.is_call ())
-@@ -3740,18 +3745,6 @@ track_regs ()
- if (!set || !ii.get_def ())
- continue;
-
-- // invalidate all which are using the value from dest since that value changed
-- rtx dst = SET_DEST(set);
-- if (MEM_P(dst))
-- {
-- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-- {
-- if (rtx_equal_p(dst, track->get_value(i)))
-- track->set(i, index, 0, index);
-- }
-- }
--
-- int dregno = ii.get_dst_regno ();
- if (dregno < 0)
- continue;
-
-
-From a8cd5ab8084d61d5d7ca31a840a737d4cf689022 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 17:43:56 +0100
-Subject: [PATCH 234/303] fix opt_strcpy()
-
----
- gcc/bbb-opts.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f971c402cf84..ca6e2acadf4d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2620,12 +2620,13 @@ opt_strcpy ()
- log ("(s) opt_strcpy condition met, removing compare and joining insns - omit reg %s\n",
- reg_names[REGNO(dst)]);
-
-- emit_insn_after (newinsn, reg2x);
--
- SET_INSN_DELETED(x2reg);
- SET_INSN_DELETED(reg2x);
- SET_INSN_DELETED(insn);
-
-+ insn = emit_insn_after (pattern, reg2x);
-+ insn_invalid_p (insn, 0);
-+
- ++change_count;
- }
- }
-
-From 0521364bbbcab54adfecf35c42cfec87ddeceb69 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 17:44:24 +0100
-Subject: [PATCH 235/303] merge from devel1
-
----
- gcc/config/m68k/amigaos.opt | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index 9c08ba43196e..d87f884f06b3 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -45,4 +45,19 @@ Specify startup binary
-
- fbbb=
- Target RejectNegative Report Var(string_bbb_opts) Joined
---fbbb=\t\tEnable Bebbo's optimizations. Default: -fbbb=+\n valid letters:\n\t\t+\t\tenable all\n\t\t-\t\tdisable all\n\t\ta\t\tadd move optimization\n\t\tc\t\tcompare to sub\n\t\te\t\teliminate dead assignments\n\t\tf\t\tshrink stack frame\n\t\tm\t\tmerge add statements\n\t\tp\t\tpropagate move pairs from loops\n\t\tr\t\tadditional reg rename pass\n\t\tv\t\tbe verbose\n\t\tx or X\t\tdump insns
-+-fbbb=Enable Bebbo's optimizations.
-++ enable all optimizations
-+a commute add move instructions
-+b use register for base addresses
-+c convert load const and compare into a sub
-+e eliminate dead assignments + redundant loads
-+f shrink stack frame
-+i use post increment on addresses
-+m merge add and move statements
-+p propagate move assignment pairs out of loops
-+r register renaming to maybe save registers
-+s a strcpy optimization
-+v be verbose
-+V be very verbose
-+x dump insns
-+Default: -fbbb=+
-
-From 8e8fcc48b69e50a83cf222e5a0166953d6bd7cbd Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 14 Nov 2017 23:30:53 +0100
-Subject: [PATCH 236/303] fix def flag in pre-/post-inc, disable elimination
- for DI
-
----
- gcc/DATESTAMP | 2 +-
- gcc/bbb-opts.c | 12 ++++++------
- 2 files changed, 7 insertions(+), 7 deletions(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index c4335f1aad48..034f28535909 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171011-233828
-+20171114-232732
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index ca6e2acadf4d..29a70640b83f 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1056,8 +1056,8 @@ insn_info::scan_rtx (rtx x)
- }
- }
-
-- if (code == CLOBBER)
-- def |= use;
-+ if (code == POST_INC || code == PRE_DEC || code == CLOBBER)
-+ def |= myuse;
- }
-
- void
-@@ -3704,9 +3704,6 @@ track_regs ()
- ii.mark_visited ();
- ii.get_track_var ()->assign (track);
-
-- if (ii.is_compare ())
-- continue;
--
- int dregno = ii.get_dst_regno ();
- unsigned def = ii.get_def ();
- if (def)
-@@ -3722,6 +3719,9 @@ track_regs ()
- track->set(dregno, index, 0, index);
- }
-
-+ if (ii.is_compare ())
-+ continue;
-+
- if (ii.is_call ())
- continue;
-
-@@ -3799,7 +3799,7 @@ opt_elim_dead_assign (int blocked_regno)
- if (!set)
- continue;
-
-- if (ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno && is_reg_dead (ii.get_dst_regno (), index))
-+ if (ii.get_dst_reg () && REG_NREGS(ii.get_dst_reg ()) == 1 && ii.get_dst_regno () != blocked_regno && is_reg_dead (ii.get_dst_regno (), index))
- {
- log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]);
- SET_INSN_DELETED(insn);
-
-From 11411a654f5ca127ba1fa43615ec543052d72cc4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 15 Nov 2017 21:26:02 +0100
-Subject: [PATCH 237/303] refs #3 - forbid pea for baserel expressions inside
- plus
-
----
- gcc/config/m68k/amigaos.h | 10 ----------
- gcc/config/m68k/m68k.md | 2 +-
- gcc/config/m68k/m68kamigaos.h | 10 ++++++++++
- 3 files changed, 11 insertions(+), 11 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 688f04e37ebb..d8b64576ef47 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -456,16 +456,6 @@ while (0)
- bool
- amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+ context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
+@@ -279,6 +285,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
--/* SBF: macro to test for const via pic_reg. */
--#define CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x) \
-- (GET_CODE(x) == CONST \
-- && GET_CODE(XEXP(x, 0)) == PLUS \
-- && REG_P(XEXP(XEXP(x, 0), 0)) \
-- && REGNO(XEXP(XEXP(x, 0), 0)) == PIC_REG \
-- && GET_CODE(XEXP(XEXP(x, 0), 1)) == CONST \
-- && GET_CODE(XEXP(XEXP(XEXP(x, 0), 1), 0)) == UNSPEC \
-- )
--
- #undef TARGET_STRUCT_VALUE_RTX
- #define TARGET_STRUCT_VALUE_RTX amigaos_struct_value_rtx
- rtx
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index c9ea341789f4..71a54cededeb 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -1566,7 +1566,7 @@
- (define_insn "pushasi"
- [(set (match_operand:SI 0 "push_operand" "=m")
- (match_operand:SI 1 "address_operand" "p"))]
-- ""
-+ "(flag_pic < 3) || GET_CODE(operands[1]) != PLUS || !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(operands[1], 0))"
- "pea %a1"
- [(set_attr "type" "pea")])
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 7dc0e57f5cdc..cd099997bf07 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -755,3 +755,13 @@ extern int amiga_is_const_pic_ref(const_rtx x);
+ ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
- extern int
- amigaos_function_arg_reg(unsigned regno);
-+
-+/* SBF: macro to test for const via pic_reg. */
-+#define CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x) \
-+ (GET_CODE(x) == CONST \
-+ && GET_CODE(XEXP(x, 0)) == PLUS \
-+ && REG_P(XEXP(XEXP(x, 0), 0)) \
-+ && REGNO(XEXP(XEXP(x, 0), 0)) == PIC_REG \
-+ && GET_CODE(XEXP(XEXP(x, 0), 1)) == CONST \
-+ && GET_CODE(XEXP(XEXP(XEXP(x, 0), 1), 0)) == UNSPEC \
-+ )
-
-From 6f8c5e9a1995a1fbb15272251bfb15019486c053 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 15 Nov 2017 21:26:30 +0100
-Subject: [PATCH 238/303] update version
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 034f28535909..b8b68f869e68 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171114-232732
-+20171115-212610
-
-From b840b61ba578ffe6e2d06b7ce8106ce6a5308f68 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 16 Nov 2017 18:47:33 +0100
-Subject: [PATCH 239/303] fix auto_inc fixups
-
----
- gcc/bbb-opts.c | 101 ++++++++++++++++++++++++++++-----------------------------
- 1 file changed, 50 insertions(+), 51 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 29a70640b83f..9770b93819e3 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -913,23 +913,41 @@ insn_info::auto_inc_fixup (int regno, int size)
- else
- XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
- }
-- else
-+ else if (get_src_mem_regno () == regno)
- {
-- rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-- // goto mem if there is an op
-- if (get_src_mem_regno () == regno && src_op)
-- mem = XEXP(mem, 1);
-+ // src mem used ?
-+ rtx mem = SET_SRC(set);
-+ if (src_op)
-+ {
-+ if (MEM_P(XEXP(mem, 0)))
-+ mem = XEXP(mem, 0);
-+ else
-+ mem = XEXP(mem, 1);
-+ }
-+ rtx plus = XEXP(mem, 0);
++ if (!ptr)
++ return;
+
-+ if (src_mem_addr == (unsigned) size)
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ src_mem_addr = 0;
-+ src_plus = false;
-+ }
-+ else
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), src_mem_addr -= size);
-+ }
+ if (size == sizeof(_Unwind_Ptr))
+ * (_Unwind_Ptr *) ptr = val;
+ else
+@@ -1612,10 +1621,10 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
+ macro because __builtin_eh_return must be invoked in the context of
+ our caller. */
-+ if (get_dst_mem_regno () == regno)
-+ {
-+ rtx mem = SET_DEST(set);
- rtx plus = XEXP(mem, 0);
-- if ((get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) == (unsigned) size)
-+ if (dst_mem_addr == (unsigned) size)
- {
- XEXP(mem, 0) = XEXP(plus, 0);
-- (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) = 0;
-- (get_dst_mem_regno () == regno ? dst_plus : src_plus) = false;
-+ dst_mem_addr = 0;
-+ dst_plus = false;
- }
- else
-- XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)),
-- (get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) -= size);
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), dst_mem_addr -= size);
- }
+-#define uw_install_context(CURRENT, TARGET) \
++#define uw_install_context(CURRENT, TARGET, INDEX) \
+ do \
+ { \
+- long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
++ long offset = uw_install_context_1 ((CURRENT), (TARGET), (INDEX)); \
+ void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
+ _Unwind_DebugHook ((TARGET)->cfa, handler); \
+ __builtin_eh_return (offset, handler); \
+@@ -1624,7 +1633,8 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
- rtx pattern = add_clobbers (insn);
-@@ -4019,7 +4037,7 @@ opt_absolute (void)
- static int
- try_auto_inc (unsigned index, insn_info & ii, rtx reg)
+ static long
+ uw_install_context_1 (struct _Unwind_Context *current,
+- struct _Unwind_Context *target)
++ struct _Unwind_Context *target,
++ int index ATTRIBUTE_UNUSED)
{
-- int regno = REGNO(reg);
-+ int const regno = REGNO(reg);
- unsigned size = GET_MODE_SIZE(ii.get_mode ());
- if (size > 4)
- return 0;
-@@ -4034,18 +4052,14 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- todo.push_back (index + 1);
-
- bool match_size = false;
-- bool ok = true;
- std::set<unsigned> visited;
-- while (ok && todo.size () > 0)
-+ while (todo.size () > 0)
- {
- unsigned pos = todo[todo.size () - 1];
- todo.pop_back ();
-
- if (pos == index)
-- {
-- ok = false;
-- break;
-- }
-+ return 0;
-
- if (visited.find (pos) != visited.end ())
- continue;
-@@ -4063,13 +4077,8 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- {
- insn_info * ll = insn2info.find (j->second)->second;
- if (ll->is_use (regno))
-- {
-- ok = false;
-- break;
-- }
-+ return 0;
- }
-- if (ok)
-- continue;
- break;
- }
-
-@@ -4078,10 +4087,7 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- break;
-
- if (jj.in_proepi ())
-- {
-- ok = false;
-- break;
-- }
-+ return 0;
-
- // add all labels
- if (jj.is_jump ())
-@@ -4097,52 +4103,45 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
-
- // can't fixup such kind of insn (yet)
- if (single_set (jj.get_insn ()) == 0)
-- {
-- ok = false;
-- break;
-- }
-+ return 0;
-+
-
- // if reg is src reg, op must be add and addend must be large enough
-- if (jj.get_src_regno () == regno || jj.get_src_mem_regno () == regno)
-+ bool fix = false;
-+ if (jj.get_src_mem_regno () == regno)
- {
-- if (jj.get_src_mem_addr () < size || (jj.get_dst_mem_regno () == regno && jj.get_dst_mem_addr () < size))
-- {
-- ok = false;
-- break;
-- }
-+ if (jj.get_src_mem_addr () < size)
-+ return 0;
-
- if (jj.get_src_mem_addr () == size)
- match_size = true;
-
-- fixups.insert (pos);
-+ fix = true;
- }
-- else if (jj.get_dst_mem_regno () == regno)
-+ if (jj.get_dst_mem_regno () == regno)
- {
- if (jj.get_dst_mem_addr () < size)
-- {
-- ok = false;
-- break;
-- }
-+ return 0;
-
- if (jj.get_dst_mem_addr () == size)
- match_size = true;
-
-- fixups.insert (pos);
-- }
-- else
-- {
-- ok = false;
-- break;
-+ fix = true;
- }
-
-+ if (!fix)
-+ return 0;
-+
-+ fixups.insert (pos);
-+
- // done if this is an add
- if (ii.is_def (regno))
- break;
- }
- }
-
-- if (!ok || !match_size || !fixups.size ())
-- return 0;;
-+ if (!match_size || !fixups.size ())
-+ return 0;
-
- if (!ii.make_post_inc (regno))
- return 0;
-
-From a22dcf21bd29bb611cffba71f44be8bd8e374369 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Fri, 17 Nov 2017 10:32:33 +0100
-Subject: [PATCH 240/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index b8b68f869e68..c6989ab7bfaf 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171115-212610
-+20171117-102900
-
-From 74fc8f7c5229526dcbeae19fc50276c872652706 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 17 Nov 2017 23:16:16 +0100
-Subject: [PATCH 241/303] modified reg tracking
-
----
- gcc/bbb-opts.c | 41 ++++++++++++++++++++++++++++++++---------
- 1 file changed, 32 insertions(+), 9 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 9770b93819e3..294959ecb283 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -144,14 +144,20 @@ class track_var
- }
-
- unsigned get_index(unsigned regno) const {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return 0;
- return indexes[regno];
- }
-
- rtx get_value(unsigned regno) const {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return 0;
- return values[regno];
- }
-
- unsigned get_version(unsigned regno) const {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return 0;
- return versions[regno];
- }
-
-@@ -169,8 +175,7 @@ class track_var
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- indexes[i] = at;
-- if (versions[i] != o->versions[0] || !values[i] || !o->values[i] || !rtx_equal_p (values[i], o->values[i]))
-+ if (versions[i] != o->versions[0] || !rtx_equal_p (values[i], o->values[i]))
- values[i] = o->values[i] = 0;
- }
- }
-@@ -181,7 +186,7 @@ class track_var
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (versions[i] != o->versions[0] || !values[i] || !o->values[i] || !rtx_equal_p (values[i], o->values[i]))
-+ if (versions[i] != o->versions[0] || !rtx_equal_p (values[i], o->values[i]))
- if (values[i])
- return false;
- }
-@@ -3723,13 +3728,13 @@ track_regs ()
- ii.get_track_var ()->assign (track);
-
- int dregno = ii.get_dst_regno ();
-- unsigned def = ii.get_def ();
-+ unsigned def = ii.get_def () & 0xffffff;
- if (def)
- {
- for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
- {
- // register changed or used somehow
-- if ( ((1 << regno) & def) || (infos[track->get_index(regno)].get_myuse() & def))
-+ if ( ((1 << regno) & def) || (track->get_index(regno) && (infos[track->get_index(regno)].get_myuse() & def)))
- track->set(regno, index, 0, index);
- }
- // clear on self update
-@@ -3827,13 +3832,19 @@ opt_elim_dead_assign (int blocked_regno)
-
- // check for redundant load
- if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno
-- && !ii.is_use (ii.get_dst_regno ()))
-+ && !ii.is_myuse (ii.get_dst_regno ()))
- {
- track_var * track = ii.get_track_var();
-+
-+// if (ii.get_src_regno() == 8 && ii.get_dst_regno() == 7)
-+// printf("%d: move %d,%d: v=%d (%d->%d), i=%d (%d->%d)\n", index, ii.get_src_regno(), ii.get_dst_regno(),
-+// track->get_version(ii.get_src_regno()), infos[track->get_version(ii.get_src_regno())].get_src_regno(), infos[track->get_version(ii.get_src_regno())].get_dst_regno(),
-+// track->get_index(ii.get_dst_regno()), infos[track->get_index(ii.get_dst_regno())].get_src_regno(), infos[track->get_index(ii.get_dst_regno())].get_dst_regno());
-+
- rtx src = SET_SRC(set);
- if (rtx_equal_p(track->get_value(ii.get_dst_regno()), src))
- {
-- if ((REG_P(src) && track->get_version(ii.get_dst_regno()) == track->get_index(REGNO(src)))
-+ if ((REG_P(src) && track->get_version(ii.get_dst_regno()) == track->get_index(ii.get_src_regno()))
- || !REG_P(src))
- {
- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-@@ -3842,6 +3853,18 @@ opt_elim_dead_assign (int blocked_regno)
- continue;
- }
- }
-+ // check reverse assignment
-+ if (REG_P(src))
-+ {
-+ if (REG_P(src) && rtx_equal_p(track->get_value(ii.get_src_regno()), SET_DEST(set))
-+ && track->get_version(ii.get_src_regno()) == track->get_index(ii.get_dst_regno()))
-+ {
-+ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
-+ }
- }
- }
- return change_count;
-@@ -4308,10 +4331,10 @@ namespace
- if (do_merge_add && opt_merge_add ())
- done = 0;
-
-- if (do_absolute && opt_absolute ())
-+ if (do_elim_dead_assign && opt_elim_dead_assign (STACK_POINTER_REGNUM))
- done = 0, update_insns ();
-
-- if (do_elim_dead_assign && opt_elim_dead_assign (STACK_POINTER_REGNUM))
-+ if (do_absolute && opt_absolute ())
- done = 0, update_insns ();
-
- if (do_autoinc && opt_autoinc ())
-
-From 7f672ad9e54bd8fc4cc1d13cac737374412481aa Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sat, 18 Nov 2017 16:16:38 +0100
-Subject: [PATCH 242/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index c6989ab7bfaf..53f5062dcd68 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171117-102900
-+20171118-161638
-
-From b4f98bfecd75e74c6f488a8c2dd25b825bcb9c13 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 19 Nov 2017 12:45:24 +0100
-Subject: [PATCH 243/303] improved function type checking for __regargs,
- __stdargs and asm register parameters
-
----
- gcc/c/c-decl.c | 29 ++++++++++++++++++--
- gcc/config/m68k/amigaos.c | 70 +++++++++++++++++++++++++++++++++--------------
- gcc/config/m68k/amigaos.h | 9 +++---
- 3 files changed, 82 insertions(+), 26 deletions(-)
-
-diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
-index b0df4e1d9a65..42ebfeb9fa90 100644
---- gcc/c/c-decl.c
-+++ gcc/c/c-decl.c
-@@ -4441,7 +4441,32 @@ c_decl_attributes (tree *node, tree attributes, int flags)
- attributes = tree_cons (get_identifier ("omp declare target"),
- NULL_TREE, attributes);
+ long i;
+ _Unwind_SpTmp sp_slot;
+@@ -1659,7 +1669,75 @@ uw_install_context_1 (struct _Unwind_Context *current,
+ else if (t && c && t != c)
+ memcpy (c, t, dwarf_reg_size_table[i]);
}
-- return decl_attributes (node, attributes, flags);
-+
-+ tree returned_attrs = decl_attributes (node, attributes, flags);
++#ifdef __AMIGA__
++ /* SBF: evil hack to patch the values for d0/d1 into the stack location.
++ * search the movem insn and count the saved regs.
++ * Now patch the values into location.
++ * Always patch d0/d1 since override is always invoked for d0/d1.
++ * Then patch all other regs which the above code omitted.
++ */
++ /* uw_install_context_1 is called from 4 different locations - each uses an unique index.
++ * So initialization is only done once.
++ */
++ static unsigned short counts[4];
++ static unsigned short masks[4];
+
-+#ifdef TARGET_AMIGA
-+ /* add an attribute to the function decl's type if there are asm register parameters. */
-+ if (TREE_CODE (*node) == FUNCTION_DECL)
++ unsigned short count = 0;
++ unsigned short reg_mask = masks[index];
++ /* init each index once. */
++ if (!reg_mask)
+ {
-+ char * synthetic = "";
-+ for (tree params = TYPE_ARG_TYPES(TREE_TYPE(*node)); params; params = TREE_CHAIN(params))
-+ {
-+ tree asmattr = lookup_attribute("asm", TYPE_ATTRIBUTES(TREE_VALUE(params)));
-+ if (asmattr)
-+ synthetic = concat(synthetic, reg_names[TREE_FIXED_CST_PTR(TREE_VALUE(asmattr))->data.low], 0);
-+ }
-+ if (strlen(synthetic) > 0)
++ /* get the return address.*/
++ unsigned short * sp = *(((unsigned short **)&current) - 1);
++ /* search the movem -x(a5),regs insn.*/
++ for (;;)
+ {
-+ tree asmid = get_identifier("asmregs");
-+ tree syntheticid = get_identifier(synthetic);
-+ tree newattr = tree_cons(asmid, syntheticid, NULL_TREE);
-+
-+ TYPE_ATTRIBUTES(TREE_TYPE(*node)) = chainon(newattr, TYPE_ATTRIBUTES(TREE_TYPE(*node)));
-+ }
-+ }
-+#endif
-+
-+ return returned_attrs;
- }
-
-
-@@ -5114,7 +5139,7 @@ push_parm_decl (const struct c_parm *parm, tree *expr)
- TYPE_ATTRIBUTES(atype) = chainon (attrs, TYPE_ATTRIBUTES(atype));
- }
- TREE_TYPE(decl) = atype;
--// printf("%s using %s, cdecl=%p, type=%p\n", IDENTIFIER_POINTER(DECL_NAME (decl), asmspec, decl, atype);
-+// printf("%s using %s, cdecl=%p, type=%p\n", IDENTIFIER_POINTER(DECL_NAME (decl)), asmspec, decl, atype);
- }
- }
- #endif
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 53e01499341d..991c2905668f 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -393,7 +393,7 @@ amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
-
- if (fntype)
- {
-- tree attrs = decl ? DECL_ATTRIBUTES(decl) : NULL;
-+ tree attrs = TYPE_ATTRIBUTES(fntype);
- if (attrs)
- {
- if (lookup_attribute ("stkparm", attrs))
-@@ -622,27 +622,57 @@ amigaos_comp_type_attributes (const_tree type1, const_tree type2)
- 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))
-+ tree attrs1 = TYPE_ATTRIBUTES(type1);
-+
-+ tree asm1 = lookup_attribute("asmregs", attrs1);
-+ tree stack1 = lookup_attribute("stkparm", attrs1);
-+ tree reg1 = lookup_attribute("regparm", attrs1);
-+
-+ tree attrs2 = TYPE_ATTRIBUTES(type2);
-+
-+ tree asm2 = lookup_attribute("asmregs", attrs2);
-+ tree stack2 = lookup_attribute("stkparm", attrs2);
-+ tree reg2 = lookup_attribute("regparm", attrs2);
-+
-+ if (reg1)
- {
-- tree attr1 = TYPE_ATTRIBUTES(arg1);
-- tree attr2 = TYPE_ATTRIBUTES(arg2);
-- if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr1))))
-- attr1 = NULL_TREE;
-- if (strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(attr2))))
-- attr2 = NULL_TREE;
-- if (attr1 && attr2)
-- {
-- if (TREE_FIXED_CST_PTR(TREE_VALUE(attr1))->data.low != TREE_FIXED_CST_PTR(TREE_VALUE(attr2))->data.low)
-- return 0;
-- }
-- else if (attr1 || attr2)
-- return 0; /* asm attribute only on one side. */
-+ if (stack2 || asm2)
-+ return 0;
-+
-+ int no1 = TREE_INT_CST_LOW(TREE_VALUE(reg1));
-+ int no2 = reg2 ? TREE_INT_CST_LOW(TREE_VALUE(reg2)) : amigaos_regparm;
-+ return no1 == no2;
++ unsigned short s = *sp++;
++// printf("%04x ", s);
++ gcc_assert(s != (unsigned short)0x4e75);// hit return? ouch!
++ if (s == (unsigned short)0x4ced)
++ break;
+ }
-+
-+ if (reg2)
++ reg_mask = *sp;
++ /* count saved regs */
++ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
+ {
-+ if (stack1 || asm1)
-+ return 0;
-+
-+ int no2 = TREE_INT_CST_LOW(TREE_VALUE(reg2));
-+ return amigaos_regparm == no2;
++ if (m & 1)
++ ++count;
++ m >>= 1;
+ }
-+
-+ if (stack1) {
-+ if (stack2)
-+ return 1;
-+ return amigaos_regparm == 0;
-+ }
-+
-+ if (stack2)
-+ return amigaos_regparm == 0;
-+
-+ if (asm1)
-+ {
-+ if (!asm2)
-+ return 0;
-+
-+ return 0 == strcmp(IDENTIFIER_POINTER(TREE_VALUE(asm1)), IDENTIFIER_POINTER(TREE_VALUE(asm2)));
- }
-- if (arg1 || arg2)
-- return 0; /* different count of parameters. */
-+
-+ if (asm2)
-+ return 0;
-+
- }
- return 1;
- }
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index d8b64576ef47..11dd88854160 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -444,10 +444,11 @@ while (0)
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
- affects_type_identity } */
- #define SUBTARGET_ATTRIBUTES \
-- { "regparm", 1, 1, true, false, false, amigaos_handle_type_attribute,\
-- false }, \
-- { "stkparm", 0, 0, true, false, false, amigaos_handle_type_attribute,\
-- false },
-+ { "asmregs", 0, 0, false, false, false, 0, true }, \
-+ { "regparm", 1, 1, false, true, true, amigaos_handle_type_attribute,\
-+ true }, \
-+ { "stkparm", 0, 0, false, true, true, amigaos_handle_type_attribute,\
-+ true },
-
- #define GOT_SYMBOL_NAME ""
-
-
-From 16411f7189d41024a5dc0b3a171b519e9295ee94 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 19 Nov 2017 12:56:25 +0100
-Subject: [PATCH 244/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 53f5062dcd68..833a789eb3c6 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171118-161638
-+20171119-125625
-
-From 5d5c1d671aef73f71094976d17cd54a709582274 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 20 Nov 2017 09:55:01 +0100
-Subject: [PATCH 245/303] refs #3 - block an invalid combined insn
-
----
- gcc/config/m68k/amigaos.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 991c2905668f..b65059edf2fa 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -941,7 +941,7 @@ amigaos_legitimate_combined_insn (rtx_insn * insn)
- return true;
-
- x = XEXP(x, 0);
-- if (GET_CODE(x) != NOT)
-+ if (GET_CODE(x) != NOT && GET_CODE(x) != NEG)
- return true;
-
- x = XEXP(x, 0);
-
-From ca2ff3994ec1def3da8e9df51c0e80614c304784 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Mon, 20 Nov 2017 16:07:27 +0100
-Subject: [PATCH 246/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 833a789eb3c6..0e38b8ced4de 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171119-125625
-+20171120-160727
-
-From 06d2e5b1b649b8f64333cdab447c70df3eb22ee9 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Nov 2017 19:31:46 +0100
-Subject: [PATCH 247/303] refs #3 - added workarounds for baserel modes
-
-added an additional pass to convert combined baserel insns into correct form
-fixed peephole optimizer to leave pea insns untouched
----
- gcc/bbb-opts.c | 179 +++++++++++++++++++++++++++++++++++------
- gcc/config/m68k/constraints.md | 2 +-
- gcc/config/m68k/m68k.md | 4 +-
- gcc/passes.c | 10 +--
- gcc/passes.def | 1 +
- gcc/recog.c | 12 +++
- gcc/tree-pass.h | 1 +
- 7 files changed, 175 insertions(+), 34 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 294959ecb283..a4fee5f446b0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -143,19 +143,25 @@ class track_var
- versions[regno] = ver;
- }
-
-- unsigned get_index(unsigned regno) const {
-+ unsigned
-+ get_index (unsigned regno) const
-+ {
- if (regno >= FIRST_PSEUDO_REGISTER)
- return 0;
- return indexes[regno];
- }
-
-- rtx get_value(unsigned regno) const {
-+ rtx
-+ get_value (unsigned regno) const
-+ {
- if (regno >= FIRST_PSEUDO_REGISTER)
- return 0;
- return values[regno];
- }
-
-- unsigned get_version(unsigned regno) const {
-+ unsigned
-+ get_version (unsigned regno) const
-+ {
- if (regno >= FIRST_PSEUDO_REGISTER)
- return 0;
- return versions[regno];
-@@ -948,7 +954,7 @@ insn_info::auto_inc_fixup (int regno, int size)
- if (dst_mem_addr == (unsigned) size)
- {
- XEXP(mem, 0) = XEXP(plus, 0);
-- dst_mem_addr = 0;
-+ dst_mem_addr = 0;
- dst_plus = false;
- }
- else
-@@ -3029,7 +3035,7 @@ track_sp ()
-
- // if sp is used as source, we cannot shrink the stack yet
- // too complicated
-- if (ii.get_src_regno() == STACK_POINTER_REGNUM)
-+ if (ii.get_src_regno () == STACK_POINTER_REGNUM)
- return -1;
- }
-
-@@ -3699,13 +3705,12 @@ track_regs ()
- track_var * const track = todo.begin ()->second;
- todo.erase (todo.begin ());
-
--
- for (unsigned index = startpos; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-
- // already visited?
-- if (index != startpos && ii.is_visited () && ii.get_track_var ()->no_merge_needed(track))
-+ if (index != startpos && ii.is_visited () && ii.get_track_var ()->no_merge_needed (track))
- break;
-
- // only keep common values at labels
-@@ -3734,12 +3739,13 @@ track_regs ()
- for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
- {
- // register changed or used somehow
-- if ( ((1 << regno) & def) || (track->get_index(regno) && (infos[track->get_index(regno)].get_myuse() & def)))
-- track->set(regno, index, 0, index);
-+ if (((1 << regno) & def)
-+ || (track->get_index (regno) && (infos[track->get_index (regno)].get_myuse () & def)))
-+ track->set (regno, index, 0, index);
- }
- // clear on self update
-- if (def & ii.get_myuse())
-- track->set(dregno, index, 0, index);
-+ if (def & ii.get_myuse ())
-+ track->set (dregno, index, 0, index);
- }
-
- if (ii.is_compare ())
-@@ -3760,7 +3766,7 @@ track_regs ()
- todo.insert (std::make_pair (i->second, new track_var (track)));
-
- if (set && GET_CODE(SET_SRC(set)) == IF_THEN_ELSE)
-- continue;
-+ continue;
-
- // unconditional jump
- break;
-@@ -3784,17 +3790,17 @@ track_regs ()
- unsigned version;
- if (GET_CODE(src) != CONST_INT && GET_CODE(src) != CONST_FIXED && GET_CODE(src) != CONST_DOUBLE)
- {
-- if (ii.get_src_regno() >= 0)
-- version = track->get_index(ii.get_src_regno());
-- else if (ii.get_src_mem_regno() >= 0)
-- version = track->get_index(ii.get_src_mem_regno());
-+ if (ii.get_src_regno () >= 0)
-+ version = track->get_index (ii.get_src_regno ());
-+ else if (ii.get_src_mem_regno () >= 0)
-+ version = track->get_index (ii.get_src_mem_regno ());
- else
- version = index;
- }
- else
- version = 0;
-
-- track->set(dregno, index, src, version);
-+ track->set (dregno, index, src, version);
- }
- delete track;
- }
-@@ -3822,7 +3828,8 @@ opt_elim_dead_assign (int blocked_regno)
- if (!set)
- continue;
-
-- if (ii.get_dst_reg () && REG_NREGS(ii.get_dst_reg ()) == 1 && ii.get_dst_regno () != blocked_regno && is_reg_dead (ii.get_dst_regno (), index))
-+ if (ii.get_dst_reg () && REG_NREGS(ii.get_dst_reg ()) == 1 && ii.get_dst_regno () != blocked_regno
-+ && is_reg_dead (ii.get_dst_regno (), index))
- {
- log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]);
- SET_INSN_DELETED(insn);
-@@ -3834,7 +3841,7 @@ opt_elim_dead_assign (int blocked_regno)
- if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno
- && !ii.is_myuse (ii.get_dst_regno ()))
- {
-- track_var * track = ii.get_track_var();
-+ track_var * track = ii.get_track_var ();
-
- // if (ii.get_src_regno() == 8 && ii.get_dst_regno() == 7)
- // printf("%d: move %d,%d: v=%d (%d->%d), i=%d (%d->%d)\n", index, ii.get_src_regno(), ii.get_dst_regno(),
-@@ -3842,9 +3849,9 @@ opt_elim_dead_assign (int blocked_regno)
- // track->get_index(ii.get_dst_regno()), infos[track->get_index(ii.get_dst_regno())].get_src_regno(), infos[track->get_index(ii.get_dst_regno())].get_dst_regno());
-
- rtx src = SET_SRC(set);
-- if (rtx_equal_p(track->get_value(ii.get_dst_regno()), src))
-+ if (rtx_equal_p (track->get_value (ii.get_dst_regno ()), src))
- {
-- if ((REG_P(src) && track->get_version(ii.get_dst_regno()) == track->get_index(ii.get_src_regno()))
-+ if ((REG_P(src) && track->get_version (ii.get_dst_regno ()) == track->get_index (ii.get_src_regno ()))
- || !REG_P(src))
- {
- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-@@ -3856,8 +3863,8 @@ opt_elim_dead_assign (int blocked_regno)
- // check reverse assignment
- if (REG_P(src))
- {
-- if (REG_P(src) && rtx_equal_p(track->get_value(ii.get_src_regno()), SET_DEST(set))
-- && track->get_version(ii.get_src_regno()) == track->get_index(ii.get_dst_regno()))
-+ if (REG_P(src) && rtx_equal_p (track->get_value (ii.get_src_regno ()), SET_DEST(set))
-+ && track->get_version (ii.get_src_regno ()) == track->get_index (ii.get_dst_regno ()))
- {
- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
- SET_INSN_DELETED(insn);
-@@ -4128,7 +4135,6 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- if (single_set (jj.get_insn ()) == 0)
- return 0;
-
--
- // if reg is src reg, op must be add and addend must be large enough
- bool fix = false;
- if (jj.get_src_mem_regno () == regno)
-@@ -4379,3 +4385,128 @@ make_pass_bbb_optimizations (gcc::context * ctxt)
- {
- return new pass_bbb_optimizations (ctxt);
- }
-+
-+namespace
-+{
-+
-+ const pass_data pass_data_bbb_baserel =
-+ { RTL_PASS, /* type */
-+ "bebbo's-baserel fixer", /* name */
-+ OPTGROUP_NONE, /* optinfo_flags */
-+ TV_NONE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ };
-+
-+ class pass_bbb_baserel : public rtl_opt_pass
-+ {
-+ public:
-+ pass_bbb_baserel (gcc::context *ctxt) :
-+ rtl_opt_pass (pass_data_bbb_baserel, ctxt), pp (0)
-+ {
-+ }
-+
-+ /* opt_pass methods: */
-+ virtual bool
-+ gate (function *)
-+ {
-+ return TARGET_AMIGA && flag_pic >= 3;
-+ }
-+
-+ virtual unsigned int
-+ execute (function *)
-+ {
-+ return execute_bbb_baserel ();
-+ }
-+
-+ opt_pass *
-+ clone ()
-+ {
-+ pass_bbb_baserel * bbb = new pass_bbb_baserel (m_ctxt);
-+ return bbb;
-+ }
-+
-+ unsigned int pp;
-+
-+ unsigned
-+ execute_bbb_baserel (void);
-+ };
-+// class pass_bbb_optimizations
-+
-+ /* Main entry point to the pass. */
-+ unsigned
-+ pass_bbb_baserel::execute_bbb_baserel (void)
-+ {
-+ rtx_insn *insn, *next;
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (NONJUMP_INSN_P(insn))
-+ {
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ rtx * src = &SET_SRC(set);
-+ if (MEM_P(*src))
-+ src = &XEXP(*src, 0);
-+
-+ bool ispicref = false;
-+ // fix add PLUS/MINUS into the unspec offset
-+ if (GET_CODE(*src) == PLUS || GET_CODE(*src) == MINUS)
-+ {
-+ if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(*src, 0)))
-+ {
-+ bool isplus = GET_CODE(*src) == PLUS;
-+ rtx offset = XEXP(*src, 1);
-+
-+ // unlink PLUS/MINUS
-+ *src = XEXP(*src, 0);
-+
-+ rtx plus = XEXP(*src, 0);
-+ rtx cnst = XEXP(plus, 1);
-+ rtx unspec = XEXP(cnst, 0);
-+
-+ XVECEXP(unspec, 0, 0) = gen_rtx_PLUS(SImode, XVECEXP(unspec, 0, 0), gen_rtx_CONST_INT (SImode, isplus ? INTVAL(offset) : -INTVAL(offset)));
-+
-+ ispicref = true;
-+ }
-+ }
-+ else
-+ ispicref = CONST_PLUS_PIC_REG_CONST_UNSPEC_P(*src);
-+
-+ if (ispicref)
-+ {
-+ rtx dest = SET_DEST(set);
-+ if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC
-+ )
-+ {
-+ // split the insn
-+ rtx reg = gen_reg_rtx (Pmode);
-+
-+ rtx pat0 = gen_rtx_SET(reg, *src);
-+ rtx_insn * n0 = emit_insn_before(pat0, insn);
-+
-+ rtx pat1 = gen_rtx_SET(dest, reg);
-+ rtx_insn * n1 = emit_insn_before(pat1, insn);
-+
-+ SET_INSN_DELETED(insn);
-+ }
-+ }
-+ }
-+ }
-+
-+ return 0;
-+ }
-+
-+} // anon namespace
-+
-+rtl_opt_pass *
-+make_pass_bbb_baserel (gcc::context * ctxt)
-+{
-+ return new pass_bbb_baserel (ctxt);
-+}
-diff --git a/gcc/config/m68k/constraints.md b/gcc/config/m68k/constraints.md
-index 94a785dc95b6..0d9b1b69ab18 100644
---- gcc/config/m68k/constraints.md
-+++ gcc/config/m68k/constraints.md
-@@ -101,7 +101,7 @@
- "Used for operands that satisfy 's' without PIC stuff, when -mpcrel is not in effect."
- (and (match_code "symbol_ref,label_ref,const")
- (match_test "!TARGET_PCREL")
-- (match_test "!flag_pic || GET_CODE(op) != CONST || GET_CODE (XEXP (op, 0)) == SYMBOL_REF || GET_CODE (XEXP (op, 0)) == LABEL_REF")))
-+ (match_test "!flag_pic || !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(op)")))
-
- (define_memory_constraint "Q"
- "Means address register indirect addressing mode."
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index 71a54cededeb..906fde496031 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -1564,9 +1564,9 @@
- ;; so we will prefer it to them.
-
- (define_insn "pushasi"
-- [(set (match_operand:SI 0 "push_operand" "=m")
-+ [(set (match_operand:SI 0 "push_operand" "=<")
- (match_operand:SI 1 "address_operand" "p"))]
-- "(flag_pic < 3) || GET_CODE(operands[1]) != PLUS || !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(operands[1], 0))"
-+ ""
- "pea %a1"
- [(set_attr "type" "pea")])
-
-diff --git a/gcc/passes.c b/gcc/passes.c
-index 321adbc61e2d..407160f4e4d6 100644
---- gcc/passes.c
-+++ gcc/passes.c
-@@ -2276,18 +2276,14 @@ void dump_insns(char const * name)
- for (insn = get_insns(); insn; insn = next)
- {
- next = NEXT_INSN(insn);
-- debug_rtx(insn);
--#if 0
-+#if 1
- if (NONJUMP_INSN_P (insn))
- {
-- rtx x, y, set= single_set (insn);
-+ rtx set= single_set (insn);
- if (!set)
- continue;
-- x = y = SET_SRC(set);
-
-- while (GET_CODE(y) == CONST || GET_CODE(y) == PLUS)
-- y = XEXP(y, 0);
-- if (x != y && REG_P(y) && REGNO(y) == PIC_REG)
-+ if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(SET_SRC(set)) && MEM_P(SET_DEST(set)))
- debug_rtx(insn);
- }
- #endif
-diff --git a/gcc/passes.def b/gcc/passes.def
-index 6af49b56fb03..61d0e4d47377 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -386,6 +386,7 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_gen_hsail);
-
- NEXT_PASS (pass_expand);
-+ NEXT_PASS (pass_bbb_baserel);
-
- NEXT_PASS (pass_rest_of_compilation);
- PUSH_INSERT_PASSES_WITHIN (pass_rest_of_compilation)
-diff --git a/gcc/recog.c b/gcc/recog.c
-index 92b2aa31a777..1b215f350fd6 100644
---- gcc/recog.c
-+++ gcc/recog.c
-@@ -3249,9 +3249,21 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
- rtx_insn *new_insn;
- bool was_call = false;
-
-+#ifdef TARGET_AMIGA
-+ /* SBF: splitting may yield invalid insns -> avoid it for the special pea insn! */
-+ for (int i = 0; i <= match_len; ++i)
-+ {
-+ rtx_insn * insn0 = peep2_insn_data[i].insn;
-+ rtx set0 = single_set(insn0);
-+ if (set0 && CONST_PLUS_PIC_REG_CONST_UNSPEC_P(SET_SRC(set0)) && MEM_P(SET_DEST(set0)))
-+ return 0;
++ masks[index] = reg_mask;
++ counts[index] = count;
+ }
-+#endif
-+
- /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
- match more than one insn, or to be split into more than one insn. */
- old_insn = peep2_insn_data[peep2_current].insn;
-+
- if (RTX_FRAME_RELATED_P (old_insn))
- {
- bool any_note = false;
-diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
-index b3f66ad529b9..76c0996850f4 100644
---- gcc/tree-pass.h
-+++ gcc/tree-pass.h
-@@ -591,6 +591,7 @@ extern rtl_opt_pass *make_pass_branch_target_load_optimize2 (gcc::context
- extern rtl_opt_pass *make_pass_leaf_regs (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_split_before_sched2 (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_bbb_optimizations (gcc::context *ctxt);
-+extern rtl_opt_pass *make_pass_bbb_baserel (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_compare_elim_after_reload (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_sched2 (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_stack_regs (gcc::context *ctxt);
-
-From 4032d56eb771309d6aac6cbee68ce0bd2412e3e4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 23 Nov 2017 20:18:51 +0100
-Subject: [PATCH 248/303] refs #3 fix npe if pattern == 0
-
----
- gcc/recog.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/gcc/recog.c b/gcc/recog.c
-index 1b215f350fd6..de2340518e52 100644
---- gcc/recog.c
-+++ gcc/recog.c
-@@ -3254,6 +3254,8 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
- for (int i = 0; i <= match_len; ++i)
- {
- rtx_insn * insn0 = peep2_insn_data[i].insn;
-+ if (!PATTERN(insn0))
-+ continue;
- rtx set0 = single_set(insn0);
- if (set0 && CONST_PLUS_PIC_REG_CONST_UNSPEC_P(SET_SRC(set0)) && MEM_P(SET_DEST(set0)))
- return 0;
-
-From 6c1e4ac7b3e47db3795aecf5780244bd2d3f86a1 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Thu, 23 Nov 2017 20:35:57 +0100
-Subject: [PATCH 249/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 0e38b8ced4de..a3ce57172f94 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171120-160727
-+20171123-203556
-
-From 89ee14d7bf65457e1b5e7f0f4f02d2e36dd31296 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 25 Nov 2017 19:53:48 +0100
-Subject: [PATCH 250/303] print the invalid insn if invalid expression as
- operand
-
----
- gcc/final.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/gcc/final.c b/gcc/final.c
-index 420ac2b08fa1..009d8eca6baf 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -4002,6 +4002,7 @@ output_addr_const (FILE *file, rtx x)
- if (targetm.asm_out.output_addr_const_extra (file, x))
- break;
-
-+ debug_rtx(current_output_insn);
- output_operand_lossage ("invalid expression as operand");
- }
- }
-
-From 6d7603c860ea47e19102eabe262c7cd34d7ab304 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 25 Nov 2017 19:54:52 +0100
-Subject: [PATCH 251/303] use the default include folder (was non existant
- os-include)
-
----
- gcc/config/m68k/m68kamigaos.h | 16 +---------------
- 1 file changed, 1 insertion(+), 15 deletions(-)
-
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index cd099997bf07..0e982c12da9c 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -686,22 +686,8 @@ amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
- #undef MAX_OFILE_ALIGNMENT
- #define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT)
-
--#if 0
--#undef INCLUDE_DEFAULTS
--#define INCLUDE_DEFAULTS \
-- { \
-- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, \
-- GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT, 0 }, \
-- { GCC_INCLUDE_DIR, "GCC", 0, 0 }, \
-- { CROSS_INCLUDE_DIR "/../../os-include", "GCC", 0, 0 }, \
-- { TOOL_INCLUDE_DIR "/../ndk/include", "GCC", 0, 0 }, \
-- { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 }, \
-- { 0, 0, 0, 0 } \
-- }
--#endif
--
- #undef FIXED_INCLUDE_DIR
--#define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../os-include"
-+#define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../include"
-
- // this disables tree_loop_distribute_patterns
- #define C_COMMON_OVERRIDE_OPTIONS flag_no_builtin = 1
-
-From e25ebad9d63114a43b258f2045c646b8b090ebee Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 25 Nov 2017 20:39:19 +0100
-Subject: [PATCH 252/303] fixed warnings
-
----
- gcc/c/c-decl.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
-index 42ebfeb9fa90..642829b828c7 100644
---- gcc/c/c-decl.c
-+++ gcc/c/c-decl.c
-@@ -4448,12 +4448,12 @@ c_decl_attributes (tree *node, tree attributes, int flags)
- /* add an attribute to the function decl's type if there are asm register parameters. */
- if (TREE_CODE (*node) == FUNCTION_DECL)
- {
-- char * synthetic = "";
-+ char const * synthetic = "";
- for (tree params = TYPE_ARG_TYPES(TREE_TYPE(*node)); params; params = TREE_CHAIN(params))
- {
- tree asmattr = lookup_attribute("asm", TYPE_ATTRIBUTES(TREE_VALUE(params)));
- if (asmattr)
-- synthetic = concat(synthetic, reg_names[TREE_FIXED_CST_PTR(TREE_VALUE(asmattr))->data.low], 0);
-+ synthetic = concat(synthetic, reg_names[TREE_FIXED_CST_PTR(TREE_VALUE(asmattr))->data.low], NULL);
- }
- if (strlen(synthetic) > 0)
- {
-
-From 6dda10eb7bc66196a2e359d87dc9c832eed982f1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 25 Nov 2017 20:40:33 +0100
-Subject: [PATCH 253/303] added checks to prevent invalid baserel insns plus
- some converions into valid insns for better code
-
----
- gcc/bbb-opts.c | 16 +--
- gcc/config/m68k/amigaos-protos.h | 3 +-
- gcc/config/m68k/amigaos.c | 281 ++++++++++++++++++++-------------------
- gcc/config/m68k/amigaos.h | 41 ++++--
- gcc/config/m68k/m68k.c | 21 ++-
- 5 files changed, 193 insertions(+), 169 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index a4fee5f446b0..2d3280230207 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -4461,19 +4461,7 @@ namespace
- {
- if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(*src, 0)))
- {
-- bool isplus = GET_CODE(*src) == PLUS;
-- rtx offset = XEXP(*src, 1);
--
-- // unlink PLUS/MINUS
-- *src = XEXP(*src, 0);
--
-- rtx plus = XEXP(*src, 0);
-- rtx cnst = XEXP(plus, 1);
-- rtx unspec = XEXP(cnst, 0);
--
-- XVECEXP(unspec, 0, 0) = gen_rtx_PLUS(SImode, XVECEXP(unspec, 0, 0), gen_rtx_CONST_INT (SImode, isplus ? INTVAL(offset) : -INTVAL(offset)));
--
-- ispicref = true;
-+ amigaos_add_offset_to_symbol(src);
- }
- }
- else
-@@ -4482,7 +4470,7 @@ namespace
- if (ispicref)
- {
- rtx dest = SET_DEST(set);
-- if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC
-+ if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC
- )
- {
- // split the insn
-diff --git a/gcc/config/m68k/amigaos-protos.h b/gcc/config/m68k/amigaos-protos.h
-index 97733002f4f9..ce20a17d1840 100644
---- gcc/config/m68k/amigaos-protos.h
-+++ gcc/config/m68k/amigaos-protos.h
-@@ -34,8 +34,6 @@ extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree, tree);
- #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
- (amigaos_init_cumulative_args(&(CUM), (FNTYPE), (INDIRECT)))
-
--
--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);
-@@ -56,3 +54,4 @@ extern tree amigaos_handle_decl_attribute (tree *, tree, tree, int, bool *);
- extern tree amigaos_handle_type_attribute (tree *, tree, tree, int, bool *);
- #endif
-
-+extern void amigaos_add_offset_to_symbol(rtx *);
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index b65059edf2fa..9d2fc73d35f3 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -148,26 +148,6 @@ amigaos_encode_section_info (tree decl, rtx rtl, int first)
- }
- }
-
--/* 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. */
-
-@@ -242,53 +222,6 @@ amigaos_prologue_begin_hook (FILE *stream, int 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)
-@@ -676,58 +609,9 @@ amigaos_comp_type_attributes (const_tree type1, const_tree type2)
- }
- return 1;
- }
--
--/* 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). */
--#if 0
--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
-- }
--#endif
--
- /* end-GG-local */
-
--/* Handle a "regparm", "stkparm" attribute;
-+/* Handle a regparm, stkparm, saveds attribute;
- arguments as in struct attribute_spec.handler. */
- tree
- amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-@@ -915,35 +799,156 @@ amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
- return 0;
- }
++ else
++ count = counts[index];
--/*
-- * decline src like:
--(plus:SI (reg/f:SI 0 d0 [210])
-- (const:SI (minus:SI (not:SI (reg:SI 12 a4))
-+/**
-+ * Necessary to block some funny invalid combinations if baserel is used:
- *
-+(const:SI (minus:SI (neg:SI (reg:SI 12 a4))
-+ (const:SI (plus:SI (unspec:SI [
-+ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
-+ (const_int 0 [0])
-+ ] 6)
-+
-+(plus:SI (reg:SI 10 a2)
-+ (const:SI (minus:SI (neg:SI (reg:SI 12 a4))
-+ (const:SI (plus:SI (unspec:SI [
-+ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
-+ (const_int 0 [0])
-+ ] 6)
-+ (const_int 1234 [0xe00]))))))) xyz.c:41 465 {*lea}
++ /* regs are saved below local vars -> start at current */
++ int * p = ((int *)current) - count;
+
- */
- bool
--amigaos_legitimate_combined_insn (rtx_insn * insn)
-+amigaos_legitimate_src (rtx src)
- {
-- rtx set = single_set(insn);
-- if (!set)
-+ if (flag_pic < 3)
- return true;
-
-- rtx x = SET_SRC(set);
-- if (GET_CODE(x) != PLUS)
-- return true;
-+ if (GET_CODE(src) == PLUS || GET_CODE(src) == MINUS)
-+ {
-+ rtx x = XEXP(src, 0);
-+ if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x))
-+ {
-+ amigaos_add_offset_to_symbol(&src);
-+ return true;
-+ }
-
-- x = XEXP(x, 1);
-- if (GET_CODE(x) != CONST)
-- return true;
-+ return amigaos_legitimate_src(x) && amigaos_legitimate_src(XEXP(src, 1));
-+ }
-
-- x = XEXP(x, 0);
-- if (GET_CODE(x) != MINUS)
-- return true;
-+ if (GET_CODE(src) == CONST)
++ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
+ {
-+ rtx op = XEXP(src, 0);
-+ if (GET_CODE(op) == MINUS || GET_CODE(op) == PLUS)
++ if (m & 1)
+ {
-+ rtx x = XEXP(op, 0);
-+ if (GET_CODE(x) == NOT || GET_CODE(x) == NEG)
++ if (i <= 1 || (!current->reg[i] && (target->reg[i] || target->by_value[i])))
+ {
-+ rtx reg = XEXP(x, 0);
-+ if (!REG_P(reg))
-+ return true;
-
-- x = XEXP(x, 0);
-- if (GET_CODE(x) != NOT && GET_CODE(x) != NEG)
-- return true;
-+// debug_rtx(src);
-+ return false;
++ int old = *p;
++ /* not set by the code above - set it here */
++ if (i <= 1) // use the override values for d0/d1
++ *p = overregs[i];
++ else
++ if (target->by_value[i])
++ *p = (int)target->reg[i];
++ else
++ *p = *(int*)target->reg[i];
++// printf("patch reg %d from %08lx to %08lx\n", i, old, *p);
+ }
++ ++p;
+ }
-+
-+ if (GET_CODE(op) == UNSPEC)
-+ {
-+// debug_rtx(src);
-+ return false;
-+ }
++ m >>= 1;
+ }
-
-- x = XEXP(x, 0);
-- return !REG_P(x);
-+ return true;
- }
-+
-+void amigaos_add_offset_to_symbol(rtx * src)
-+{
-+ static char num[16];
-+ bool isplus = GET_CODE(*src) == PLUS;
-+ rtx offset = XEXP(*src, 1);
-+ sprintf(num, "%d", (int)INTVAL(offset));
-+
-+ /* unlink PLUS/MINUS */
-+ *src = XEXP(*src, 0);
-+
-+ rtx plus = XEXP(*src, 0);
-+ rtx cnst = XEXP(plus, 1);
-+ rtx unspec = XEXP(cnst, 0);
-+ rtx sym = XVECEXP(unspec, 0, 0);
-+ const char * s = XSTR(sym, 0);
-+
-+ /* create a new symbol containing the offset. */
-+ const char * t = concat(s, isplus ? "+" : "-", num, NULL);
-+ XVECEXP(unspec, 0, 0) = gen_rtx_SYMBOL_REF(Pmode, t);
-+}
-+
-+
-+void
-+amigaos_restore_a4 (void)
-+ {
-+ if (flag_pic >= 3)
-+ {
-+ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
-+ tree attr = lookup_attribute ("saveds", attrs);
-+ if (attr || TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4)
-+ {
-+ rtx a4 = gen_rtx_ASM_INPUT_loc(VOIDmode, "\tlea ___init_a4,a4", DECL_SOURCE_LOCATION (current_function_decl));
-+ a4->volatil = 1;
-+ emit_insn(a4);
-+ }
-+ }
-+ }
+
-+void
-+amigaos_alternate_frame_setup_f (int fsize)
-+ {
-+#if 0
-+ 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);
+#endif
-+ }
-+
-+void
-+amigaos_alternate_frame_setup (int fsize)
-+ {
-+#if 0
-+ 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);
-+#endif
-+ }
-+
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 11dd88854160..fe300515fa5f 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -1,4 +1,7 @@
- /* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ *
-+ * This file is only included and used inside m68k.c to define the target.
-+ *
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
- Free Software Foundation, Inc.
- Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch).
-@@ -288,16 +291,6 @@ while (0)
- #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)
-
-@@ -445,6 +438,7 @@ while (0)
- affects_type_identity } */
- #define SUBTARGET_ATTRIBUTES \
- { "asmregs", 0, 0, false, false, false, 0, true }, \
-+ { "saveds", 0, 0, false, true, true, amigaos_handle_type_attribute, false }, \
- { "regparm", 1, 1, false, true, true, amigaos_handle_type_attribute,\
- true }, \
- { "stkparm", 0, 0, false, true, true, amigaos_handle_type_attribute,\
-@@ -469,7 +463,26 @@ rtx
- amigaos_static_chain_rtx(const_tree fntype,
- bool incoming ATTRIBUTE_UNUSED);
-
--#undef TARGET_LEGITIMATE_COMBINED_INSN
--#define TARGET_LEGITIMATE_COMBINED_INSN amigaos_legitimate_combined_insn
--bool
--amigaos_legitimate_combined_insn (rtx_insn *insn ATTRIBUTE_UNUSED);
-+
-+extern bool
-+amigaos_legitimate_src (rtx src);
-+
-+extern void
-+amigaos_restore_a4 (void);
-+
-+extern void
-+amigaos_alternate_frame_setup_f (int fsize);
-+
-+extern void
-+amigaos_alternate_frame_setup (int fsize);
-+
-+
-+#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND
-+
-+#define ALTERNATE_FRAME_SETUP_F(FSIZE) \
-+ (amigaos_alternate_frame_setup_f ((FSIZE)))
-+
-+#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND
-+
-+#define ALTERNATE_FRAME_SETUP(FSIZE) \
-+ (amigaos_alternate_frame_setup ((FSIZE)))
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index ed9b76caf11d..4d719a0f3680 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -1058,6 +1058,11 @@ m68k_expand_prologue (void)
-
- if (frame_pointer_needed)
- {
-+#ifdef TARGET_AMIGA
-+ if (HAVE_ALTERNATE_FRAME_SETUP_F (fsize_with_regs))
-+ ALTERNATE_FRAME_SETUP_F (fsize_with_regs);
-+ else
-+#endif
- if (fsize_with_regs == 0 && TUNE_68040)
- {
- /* On the 68040, two separate moves are faster than link.w 0. */
-@@ -1067,6 +1072,10 @@ m68k_expand_prologue (void)
- m68k_set_frame_related (emit_move_insn (frame_pointer_rtx,
- stack_pointer_rtx));
- }
-+#ifdef TARGET_AMIGA
-+ else if (HAVE_ALTERNATE_FRAME_SETUP (fsize_with_regs))
-+ ALTERNATE_FRAME_SETUP (fsize_with_regs);
-+#endif
- else if (fsize_with_regs < 0x8000 || TARGET_68020)
- m68k_set_frame_related
- (emit_insn (gen_link (frame_pointer_rtx,
-@@ -1168,6 +1177,10 @@ m68k_expand_prologue (void)
- if (!TARGET_SEP_DATA
- && crtl->uses_pic_offset_table && flag_pic < 3)
- emit_insn (gen_load_got (pic_offset_table_rtx));
-+
-+#ifdef TARGET_AMIGA
-+ amigaos_restore_a4 ();
-+#endif
- }
-
- /* Return true if a simple (return) instruction is sufficient for this
-@@ -2163,6 +2176,8 @@ m68k_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
- /* SBF: the baserel(32) const plus pic_ref, symbol is an address. */
- if (amiga_is_const_pic_ref(x))
- return true;
-+ if (!amigaos_legitimate_src(x))
-+ return false;
- #endif
+ /* If the current frame doesn't have a saved stack pointer, then we
+ need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
+ pointer value reloaded. */
+diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
+index 7413b55e3fab..bf07725ac840 100644
+--- libgcc/unwind.inc
++++ libgcc/unwind.inc
+@@ -132,7 +132,7 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
+ if (code != _URC_INSTALL_CONTEXT)
+ return code;
- return m68k_decompose_address (mode, x, strict_p, &address);
-@@ -2185,7 +2200,11 @@ m68k_legitimate_mem_p (rtx x, struct m68k_address *address)
- bool
- m68k_legitimate_constant_p (machine_mode mode, rtx x)
- {
-- return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x);
-+ return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x)
-+#ifdef TARGET_AMIGA
-+ && amigaos_legitimate_src (x)
-+#endif
-+ ;
+- uw_install_context (&this_context, &cur_context);
++ uw_install_context (&this_context, &cur_context, 0);
}
- /* Return true if X matches the 'Q' constraint. It must be a memory
-
-From 06f886edaaf71078005b5a79e727c279eb3249ab Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 25 Nov 2017 23:16:19 +0100
-Subject: [PATCH 254/303] fix opt_autoinc: handle nested neg/not correctly
-
----
- gcc/bbb-opts.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 2d3280230207..b6f630bd6522 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -850,8 +850,14 @@ insn_info::make_post_inc (int regno)
- if (is_compare ())
- set = SET_SRC(set);
- rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-+
- if (src_op && get_src_mem_regno () == regno)
-- mem = XEXP(mem, 1);
-+ {
-+ if (src_op == NEG || src_op == NOT)
-+ mem = XEXP(mem, 0);
-+ else
-+ mem = XEXP(mem, 1);
-+ }
-
- rtx reg = XEXP(mem, 0);
-
-
-From 6095eeeb8f75626e72e6e3f023b4bb2dfebf7b6e Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 25 Nov 2017 23:17:43 +0100
-Subject: [PATCH 255/303] refs #3: correct fix for peephole optimizer
-
----
- gcc/config/m68k/m68k.md | 4 +++-
- gcc/recog.c | 13 -------------
- 2 files changed, 3 insertions(+), 14 deletions(-)
-
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index 906fde496031..7b6f69835d10 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -7204,6 +7204,7 @@
- "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
-
- ;; Changing pea X.w into a move.l is no real win here.
-+;; SBF: also disable converting pea for baserel insns!
- (define_peephole2
- [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
- (match_operand:SI 0 "const_int_operand" "")))
-@@ -7213,7 +7214,8 @@
- && !reg_mentioned_p (stack_pointer_rtx, operands[2])
- && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
- && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
-- && !valid_mov3q_const (INTVAL (operands[2])))"
-+ && !valid_mov3q_const (INTVAL (operands[2])))
-+ && !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(operands[2])"
- [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
- (set (match_dup 1) (match_dup 2))]
- {
-diff --git a/gcc/recog.c b/gcc/recog.c
-index de2340518e52..73d1fd1b1336 100644
---- gcc/recog.c
-+++ gcc/recog.c
-@@ -3249,19 +3249,6 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
- rtx_insn *new_insn;
- bool was_call = false;
-
--#ifdef TARGET_AMIGA
-- /* SBF: splitting may yield invalid insns -> avoid it for the special pea insn! */
-- for (int i = 0; i <= match_len; ++i)
-- {
-- rtx_insn * insn0 = peep2_insn_data[i].insn;
-- if (!PATTERN(insn0))
-- continue;
-- rtx set0 = single_set(insn0);
-- if (set0 && CONST_PLUS_PIC_REG_CONST_UNSPEC_P(SET_SRC(set0)) && MEM_P(SET_DEST(set0)))
-- return 0;
-- }
--#endif
--
- /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
- match more than one insn, or to be split into more than one insn. */
- old_insn = peep2_insn_data[peep2_current].insn;
-
-From edcaad7b5a906f1319f99f18f36cd0a9b20ef872 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sat, 25 Nov 2017 23:31:57 +0100
-Subject: [PATCH 256/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index a3ce57172f94..4b4b584889d8 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171123-203556
-+20171125-233156
-
-From ea33fc6832c62dfda09e972a526ef2842a3efe85 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 26 Nov 2017 10:48:15 +0100
-Subject: [PATCH 257/303] fix insn scan if src auto_inc is present, destination
- mem reg was always regarded as modified
-
----
- gcc/bbb-opts.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index b6f630bd6522..ee4e91a99b48 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1059,7 +1059,13 @@ insn_info::scan_rtx (rtx x)
- use = u;
- myuse = mu;
- }
-+
-+ // avoid side effects from myuse -> def, e.g. adding the dst reg to def by src auto inc
-+ mu = myuse;
-+ myuse = 0;
- scan_rtx (SET_SRC(x));
-+ myuse |= mu;
-+
- int code = GET_CODE(SET_SRC(x));
- if (code == ASM_OPERANDS)
- hard |= def | use;
-@@ -4181,7 +4187,7 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- if (!ii.make_post_inc (regno))
- return 0;
-
-- log ("(i) auto_inc for %s at %d\n", reg_names[regno], index);
-+ log ("(i) auto_inc for %s at %d - %d fixups\n", reg_names[regno], index, fixups.size());
-
- // fix all offsets / adds
- for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
-
-From 73e0e6c763bd79928606dece20538b1a65a53683 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 26 Nov 2017 11:25:01 +0100
-Subject: [PATCH 258/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 4b4b584889d8..1c49eda6e46b 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171125-233156
-+20171126-112501
-
-From 28fa4c97279c23894bbabe479ec7f0675e1ac1c2 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 26 Nov 2017 12:26:06 +0100
-Subject: [PATCH 259/303] fix const_cmp_sub
-
----
- gcc/bbb-opts.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index ee4e91a99b48..277f130f1ef4 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2868,7 +2868,7 @@ opt_const_cmp_to_sub (void)
- if (GET_MODE_SIZE(i0.get_mode()) > 4)
- continue;
-- if (!i0.is_dst_reg () && (!i0.is_src_const () || i0.get_src_op () == PLUS))
-+ if (!i0.is_dst_reg () || !i0.is_src_const () || i0.get_src_op ())
- continue;
+@@ -208,7 +208,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
+ if (code != _URC_INSTALL_CONTEXT)
+ return code;
- if (i0.get_dst_regno () != i1.get_src_regno ())
-
-From d1a50a4116660763379610abfa3e150f1db1e874 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 26 Nov 2017 12:53:56 +0100
-Subject: [PATCH 260/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 1c49eda6e46b..1f73e7437484 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171126-112501
-+20171126-125355
-
-From 18c192e42fc39de08a4f6cb6f241679b28cd5efc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 26 Nov 2017 16:01:03 +0100
-Subject: [PATCH 261/303] improved attribute/option checking
-
----
- gcc/config/m68k/amigaos.c | 14 ++++++++++----
- gcc/config/m68k/amigaos.h | 6 ++++++
- gcc/config/m68k/amigaos.opt | 6 +++---
- 3 files changed, 19 insertions(+), 7 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 9d2fc73d35f3..82dfae890f9f 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -672,6 +672,15 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRI
- }
- else if (is_attribute_p ("saveds", name))
- {
-+ if (flag_pic < 3)
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute is only usable with fbaserel", IDENTIFIER_POINTER(name));
-+ }
-+ else
-+ if (flag_resident)
-+ {
-+ error ("`saveds' can't be used with resident!\n");
-+ }
- }
- }
- else
-@@ -762,10 +771,7 @@ read_only_operand (rtx operand)
- rtx
- amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED)
- {
--// if (fntype && aggregate_value_p (TREE_TYPE(fntype), fntype))
- return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
--
--// return 0;
+- uw_install_context (&this_context, &cur_context);
++ uw_install_context (&this_context, &cur_context, 1);
}
- rtx
-@@ -887,7 +893,7 @@ void amigaos_add_offset_to_symbol(rtx * src)
- void
- amigaos_restore_a4 (void)
- {
-- if (flag_pic >= 3)
-+ if (flag_pic >= 3 && !flag_resident)
- {
- tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
- tree attr = lookup_attribute ("saveds", attrs);
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index fe300515fa5f..9f166d6f57c2 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -427,6 +427,12 @@ extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
- #define SUBTARGET_OVERRIDE_OPTIONS \
- do \
- { \
-+ if (flag_resident) \
-+ { \
-+ if (flag_pic) \
-+ error ("-fbaserel and -resident are mutual exclusiv\n"); \
-+ flag_pic = flag_resident; \
-+ } \
- if (!TARGET_68020 && flag_pic==4) \
- error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \
- if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-index d87f884f06b3..07406d27a777 100644
---- gcc/config/m68k/amigaos.opt
-+++ gcc/config/m68k/amigaos.opt
-@@ -32,11 +32,11 @@ Target Report Var(flag_pic,4)
- data is addressed relative to a4 with 32 bit offsets
-
- resident
--Target Common Report Var(flag_pic,3)
-+Target Common Report Var(flag_resident,3)
- data is addressed relative to a4, linked as resident
-
- resident32
--Target Common Report Var(flag_pic,4)
-+Target Common Report Var(flag_resident,4)
- data is addressed relative to a4 with 32 bit offsets, linked as resident
-
- mcrt=
-@@ -60,4 +60,4 @@ s a strcpy optimization
- v be verbose
- V be very verbose
- x dump insns
--Default: -fbbb=+
-+Default: -fbbb=+ which yields -fbbb=abcefimprs
-
-From c14a11d08caac02a69c6a7eb76e867586113aad7 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 26 Nov 2017 16:28:46 +0100
-Subject: [PATCH 262/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 1f73e7437484..216c38355e67 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171126-125355
-+20171126-162846
-
-From 9809cd847fa66de483a6994bb8ae37e1a014abea Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 27 Nov 2017 12:33:29 +0100
-Subject: [PATCH 263/303] refs #4 - use correct name: ___a4_init
-
----
- gcc/config/m68k/amigaos.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 82dfae890f9f..de2e2999eb60 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -899,7 +899,7 @@ amigaos_restore_a4 (void)
- tree attr = lookup_attribute ("saveds", attrs);
- if (attr || TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4)
- {
-- rtx a4 = gen_rtx_ASM_INPUT_loc(VOIDmode, "\tlea ___init_a4,a4", DECL_SOURCE_LOCATION (current_function_decl));
-+ rtx a4 = gen_rtx_ASM_INPUT_loc(VOIDmode, "\tlea ___a4_init,a4", DECL_SOURCE_LOCATION (current_function_decl));
- a4->volatil = 1;
- emit_insn(a4);
- }
-
-From 486fefde971da0f1a5fb28f791b940ab7801912b Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Mon, 27 Nov 2017 12:59:17 +0100
-Subject: [PATCH 264/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 216c38355e67..ce0da3dfd125 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171126-162846
-+20171127-125916
-
-From 9147ce3cfcd7cf9a6eaa3e5793ae43fc7791c9ed Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 29 Nov 2017 19:26:05 +0100
-Subject: [PATCH 265/303] fix opt_cmp_sub, prepare support for chip attribute,
- changes to baserel handling
-
----
- gcc/bbb-opts.c | 54 +++++++++------------------
- gcc/config/m68k/amigaos-protos.h | 2 -
- gcc/config/m68k/amigaos.c | 80 +++++++++++++++++++++++++++-------------
- gcc/config/m68k/amigaos.h | 7 ++++
- gcc/config/m68k/m68k.c | 13 ++++++-
- gcc/passes.c | 7 +++-
- 6 files changed, 96 insertions(+), 67 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 277f130f1ef4..4525f77acc2a 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -177,7 +177,7 @@ class track_var
-
- /* only keep common values in both sides. */
- void
-- merge (track_var * o, unsigned at)
-+ merge (track_var * o, unsigned )
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-@@ -2732,44 +2732,29 @@ opt_commute_add_move (void)
-
- for (unsigned index = 0; index + 1 < infos.size (); ++index)
- {
-- rtx_insn * insn = infos[index].get_insn ();
-- rtx set = single_set (insn);
-- if (!set)
-- continue;
--
-- rtx reg1dst = SET_DEST(set);
-- if (!REG_P(reg1dst))
-+ insn_info & ii = infos[index];
-+ if (ii.get_dst_regno() < 8 || ii.get_dst_regno() > 15 || ii.get_src_op() != PLUS || ii.get_src_regno() == ii.get_dst_regno() || !ii.get_src_intval())
- continue;
-
-- rtx plus = SET_SRC(set);
-- if (GET_CODE(plus) != PLUS)
-- continue;
-+ insn_info & jj = infos[index + 1];
-- rtx reg1src = XEXP(plus, 0);
-- if (!REG_P(reg1src) || reg1src == reg1dst)
-+ if (!jj.get_dst_mem_reg() || jj.get_dst_mem_regno() != ii.get_src_regno()
-+ || jj.get_src_regno() == ii.get_dst_regno()
-+ || GET_MODE_SIZE(jj.get_mode()) != ii.get_src_intval())
- continue;
-
-- rtx cnst = XEXP(plus, 1);
-- if (!CONST_INT_P(cnst))
-- continue;
-+ rtx_insn * insn = ii.get_insn ();
-
-- rtx_insn * next = infos[index + 1].get_insn ();
-+ rtx_insn * next = jj.get_insn ();
- rtx set2 = single_set (next);
-- if (!set2)
-- continue;
--
- rtx dst = SET_DEST(set2);
-- if (!MEM_P(dst) || GET_MODE_SIZE(GET_MODE(dst)) != INTVAL(cnst))
-- continue;
--
-- rtx memreg = XEXP(dst, 0);
-- if (!REG_P(memreg) || REGNO(memreg) != REGNO(reg1src))
-+ if (!MEM_P(dst))
- continue;
-
-- rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), reg1dst);
-+ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), ii.get_dst_reg());
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
-- rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(reg1dst, reg1src));
-+ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(ii.get_dst_reg(), ii.get_src_reg()));
-
- if (!insn_invalid_p (newinsn, 1) && validate_change (next, &SET_DEST(set2), newmem, 1) && apply_change_group ())
- {
-@@ -2779,7 +2764,7 @@ opt_commute_add_move (void)
-
- insn = emit_insn_before (newinsn, next);
-
-- add_reg_note (next, REG_INC, reg1dst);
-+ add_reg_note (next, REG_INC, ii.get_dst_reg());
-
- ++change_count;
- }
-@@ -4470,12 +4455,7 @@ namespace
- bool ispicref = false;
- // fix add PLUS/MINUS into the unspec offset
- if (GET_CODE(*src) == PLUS || GET_CODE(*src) == MINUS)
-- {
-- if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(*src, 0)))
-- {
-- amigaos_add_offset_to_symbol(src);
-- }
-- }
-+ ispicref = CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(*src, 0));
- else
- ispicref = CONST_PLUS_PIC_REG_CONST_UNSPEC_P(*src);
-
-@@ -4489,10 +4469,12 @@ namespace
- rtx reg = gen_reg_rtx (Pmode);
-
- rtx pat0 = gen_rtx_SET(reg, *src);
-- rtx_insn * n0 = emit_insn_before(pat0, insn);
-+ //rtx_insn * n0 =
-+ emit_insn_before(pat0, insn);
+@@ -233,7 +233,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
- rtx pat1 = gen_rtx_SET(dest, reg);
-- rtx_insn * n1 = emit_insn_before(pat1, insn);
-+ //rtx_insn * n1 =
-+ emit_insn_before(pat1, insn);
+ gcc_assert (code == _URC_INSTALL_CONTEXT);
- SET_INSN_DELETED(insn);
- }
-diff --git a/gcc/config/m68k/amigaos-protos.h b/gcc/config/m68k/amigaos-protos.h
-index ce20a17d1840..e5cd6e950b52 100644
---- gcc/config/m68k/amigaos-protos.h
-+++ gcc/config/m68k/amigaos-protos.h
-@@ -53,5 +53,3 @@ extern struct rtx_def *amigaos_function_arg (CUMULATIVE_ARGS *, enum machine_mod
- extern tree amigaos_handle_decl_attribute (tree *, tree, tree, int, bool *);
- extern tree amigaos_handle_type_attribute (tree *, tree, tree, int, bool *);
- #endif
--
--extern void amigaos_add_offset_to_symbol(rtx *);
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index de2e2999eb60..ba8a5d757d21 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -682,10 +682,21 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRI
- error ("`saveds' can't be used with resident!\n");
- }
- }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to data", IDENTIFIER_POINTER(name));
-+ }
- }
- else
- {
-- warning (OPT_Wattributes, "`%s' attribute only applies to functions", IDENTIFIER_POINTER(name));
-+ if (is_attribute_p ("chip", name))
-+ {
-+ // OK
-+ }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to functions", IDENTIFIER_POINTER(name));
-+ }
- }
- return NULL_TREE ;
- }
-@@ -695,6 +706,46 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRI
- return NULL_TREE ;
+- uw_install_context (&this_context, &cur_context);
++ uw_install_context (&this_context, &cur_context, 2);
}
-+#define AMIGA_CHIP_SECTION_NAME ".datachip"
-+
-+void
-+amiga_insert_attribute (tree decl, tree * attr)
-+{
-+ if (!*attr)
-+ return;
-+
-+ tree name = TREE_PURPOSE(*attr);
-+
-+ if (is_attribute_p("chip", name))
-+ {
-+ if (!TREE_TYPE(decl) == VAR_DECL)
-+ {
-+ error ("`chip' attribute can only be specified for variables");
-+ return;
-+ }
-+
-+ if (! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
-+ {
-+ error ("`chip' attribute cannot be specified for local variables");
-+ return;
-+ }
-+ /* The decl may have already been given a section attribute from
-+ a previous declaration. Ensure they match. */
-+ if (DECL_SECTION_NAME (decl) == NULL)
-+ warning (OPT_Wattributes, "`%s' attribute is not yet supported", IDENTIFIER_POINTER(name));
-+// set_decl_section_name(decl, AMIGA_CHIP_SECTION_NAME);
-+ else if (strcmp (DECL_SECTION_NAME (decl), AMIGA_CHIP_SECTION_NAME) )
-+ {
-+ error_at (DECL_SOURCE_LOCATION(decl),
-+ "`chip' attribute conflicts with previous declaration");
-+ }
-+ }
-+ else
-+ {
-+// warning (OPT_Wattributes, "`%s' attribute unknown", IDENTIFIER_POINTER(name));
-+ }
-+}
-+
- extern bool
- m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-
-@@ -832,11 +883,10 @@ amigaos_legitimate_src (rtx src)
- if (GET_CODE(src) == PLUS || GET_CODE(src) == MINUS)
- {
- rtx x = XEXP(src, 0);
-+
-+ /** handled in print_operand_address(...) */
- if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x))
-- {
-- amigaos_add_offset_to_symbol(&src);
- return true;
-- }
-
- return amigaos_legitimate_src(x) && amigaos_legitimate_src(XEXP(src, 1));
- }
-@@ -868,28 +918,6 @@ amigaos_legitimate_src (rtx src)
- return true;
- }
--void amigaos_add_offset_to_symbol(rtx * src)
--{
-- static char num[16];
-- bool isplus = GET_CODE(*src) == PLUS;
-- rtx offset = XEXP(*src, 1);
-- sprintf(num, "%d", (int)INTVAL(offset));
--
-- /* unlink PLUS/MINUS */
-- *src = XEXP(*src, 0);
--
-- rtx plus = XEXP(*src, 0);
-- rtx cnst = XEXP(plus, 1);
-- rtx unspec = XEXP(cnst, 0);
-- rtx sym = XVECEXP(unspec, 0, 0);
-- const char * s = XSTR(sym, 0);
--
-- /* create a new symbol containing the offset. */
-- const char * t = concat(s, isplus ? "+" : "-", num, NULL);
-- XVECEXP(unspec, 0, 0) = gen_rtx_SYMBOL_REF(Pmode, t);
--}
--
--
- void
- amigaos_restore_a4 (void)
- {
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 9f166d6f57c2..723c36969ad1 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -444,6 +444,7 @@ while (0)
- affects_type_identity } */
- #define SUBTARGET_ATTRIBUTES \
- { "asmregs", 0, 0, false, false, false, 0, true }, \
-+ { "chip", 0, 0, false, true, false, amigaos_handle_type_attribute, false }, \
- { "saveds", 0, 0, false, true, true, amigaos_handle_type_attribute, false }, \
- { "regparm", 1, 1, false, true, true, amigaos_handle_type_attribute,\
- true }, \
-@@ -492,3 +493,9 @@ amigaos_alternate_frame_setup (int fsize);
+@@ -258,7 +258,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
- #define ALTERNATE_FRAME_SETUP(FSIZE) \
- (amigaos_alternate_frame_setup ((FSIZE)))
-+
-+#undef TARGET_INSERT_ATTRIBUTES
-+#define TARGET_INSERT_ATTRIBUTES amiga_insert_attribute
-+
-+void
-+amiga_insert_attribute (tree decl, tree * attr);
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 4d719a0f3680..f5daa0cbcc26 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -4835,6 +4835,14 @@ print_operand_address (FILE *file, rtx addr)
- print_operand_address(file, XEXP(addr, 0));
- return;
- }
-+ if (GET_CODE(addr) == PLUS && CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(addr, 0)))
-+ {
-+ fprintf (file, "%d+", (int) INTVAL (XEXP(addr, 1)));
-+ print_operand_address(file, XEXP(XEXP(addr, 0),0));
-+ return;
-+ }
-+
-+
- if (symbolic_operand(addr, VOIDmode))
- {
- memset (&address, 0, sizeof (address));
-@@ -4843,7 +4851,10 @@ print_operand_address (FILE *file, rtx addr)
- else
- #endif
- if (!m68k_decompose_address (QImode, addr, true, &address))
-- gcc_unreachable ();
-+ {
-+ debug_rtx(addr);
-+ gcc_unreachable ();
-+ }
+ gcc_assert (code == _URC_INSTALL_CONTEXT);
- if (address.code == PRE_DEC)
- fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
-diff --git a/gcc/passes.c b/gcc/passes.c
-index 407160f4e4d6..b216ee028245 100644
---- gcc/passes.c
-+++ gcc/passes.c
-@@ -2276,7 +2276,8 @@ void dump_insns(char const * name)
- for (insn = get_insns(); insn; insn = next)
- {
- next = NEXT_INSN(insn);
--#if 1
-+ debug_rtx(insn);
-+#if 0
- if (NONJUMP_INSN_P (insn))
- {
- rtx set= single_set (insn);
-@@ -2290,6 +2291,7 @@ void dump_insns(char const * name)
- }
+- uw_install_context (&this_context, &cur_context);
++ uw_install_context (&this_context, &cur_context, 3);
}
-+
- /* Execute PASS. */
-
- bool
-@@ -2299,7 +2301,8 @@ execute_one_pass (opt_pass *pass)
-
- bool gate_status;
-
--// dump_insns(pass->name);
-+ if (string_bbb_opts && strchr (string_bbb_opts, 'Y'))
-+ dump_insns(pass->name);
-
- /* IPA passes are executed on whole program, so cfun should be NULL.
- Other passes need function context set. */
-
-From 4a14629a3a38f9c4d043813eb36247a5a0b3adc7 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Wed, 29 Nov 2017 19:55:45 +0100
-Subject: [PATCH 266/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index ce0da3dfd125..4aee726e0fe2 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171127-125916
-+20171129-195545
-
-From e2608938b1210496cf528a280030a5906a6991e5 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 1 Dec 2017 20:06:38 +0100
-Subject: [PATCH 267/303] fix opt_auto_inc again
-
----
- gcc/bbb-opts.c | 38 +++++++++++++++++++++-----------------
- 1 file changed, 21 insertions(+), 17 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 4525f77acc2a..7c8fc94ed8a6 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -177,7 +177,7 @@ class track_var
-
- /* only keep common values in both sides. */
- void
-- merge (track_var * o, unsigned )
-+ merge (track_var * o, unsigned)
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-@@ -928,7 +928,7 @@ insn_info::auto_inc_fixup (int regno, int size)
- SET_SRC(set) = XEXP(src, 0);
- }
- else
-- XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
-+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
- }
- else if (get_src_mem_regno () == regno)
- {
-@@ -2733,14 +2733,14 @@ opt_commute_add_move (void)
- for (unsigned index = 0; index + 1 < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-- if (ii.get_dst_regno() < 8 || ii.get_dst_regno() > 15 || ii.get_src_op() != PLUS || ii.get_src_regno() == ii.get_dst_regno() || !ii.get_src_intval())
-+ if (ii.get_dst_regno () < 8 || ii.get_dst_regno () > 15 || ii.get_src_op () != PLUS
-+ || ii.get_src_regno () == ii.get_dst_regno () || !ii.get_src_intval ())
- continue;
-
- insn_info & jj = infos[index + 1];
-
-- if (!jj.get_dst_mem_reg() || jj.get_dst_mem_regno() != ii.get_src_regno()
-- || jj.get_src_regno() == ii.get_dst_regno()
-- || GET_MODE_SIZE(jj.get_mode()) != ii.get_src_intval())
-+ if (!jj.get_dst_mem_reg () || jj.get_dst_mem_regno () != ii.get_src_regno ()
-+ || jj.get_src_regno () == ii.get_dst_regno () || GET_MODE_SIZE(jj.get_mode()) != ii.get_src_intval ())
- continue;
-
- rtx_insn * insn = ii.get_insn ();
-@@ -2751,10 +2751,10 @@ opt_commute_add_move (void)
- if (!MEM_P(dst))
- continue;
-
-- rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), ii.get_dst_reg());
-+ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), ii.get_dst_reg ());
- rtx newmem = replace_equiv_address_nv (dst, pinc);
-
-- rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(ii.get_dst_reg(), ii.get_src_reg()));
-+ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(ii.get_dst_reg (), ii.get_src_reg ()));
-
- if (!insn_invalid_p (newinsn, 1) && validate_change (next, &SET_DEST(set2), newmem, 1) && apply_change_group ())
- {
-@@ -2764,7 +2764,7 @@ opt_commute_add_move (void)
-
- insn = emit_insn_before (newinsn, next);
-
-- add_reg_note (next, REG_INC, ii.get_dst_reg());
-+ add_reg_note (next, REG_INC, ii.get_dst_reg ());
-
- ++change_count;
- }
-@@ -4136,6 +4136,9 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- bool fix = false;
- if (jj.get_src_mem_regno () == regno)
- {
-+ if (jj.get_dst_regno () == regno)
-+ return 0;
-+
- if (jj.get_src_mem_addr () < size)
- return 0;
-
-@@ -4146,6 +4149,9 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- }
- if (jj.get_dst_mem_regno () == regno)
- {
-+ if (jj.get_src_regno () == regno)
-+ return 0;
-+
- if (jj.get_dst_mem_addr () < size)
- return 0;
-
-@@ -4172,7 +4178,7 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg)
- if (!ii.make_post_inc (regno))
- return 0;
-
-- log ("(i) auto_inc for %s at %d - %d fixups\n", reg_names[regno], index, fixups.size());
-+ log ("(i) auto_inc for %s at %d - %d fixups\n", reg_names[regno], index, fixups.size ());
-
- // fix all offsets / adds
- for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
-@@ -4220,13 +4226,12 @@ opt_autoinc ()
- // if ((ii.get_myuse () & 0xff0000))
- // continue;
-
-- rtx reg = 0;
- if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 && !ii.get_src_mem_addr () && !ii.get_src_autoinc ()
- && ii.get_src_mem_regno () != ii.get_dst_mem_regno () && ii.get_src_mem_regno () != ii.get_dst_regno ())
- change_count += try_auto_inc (index, ii, ii.get_src_mem_reg ());
-
-- if (!reg && ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
-- && ii.get_src_mem_regno () != ii.get_dst_mem_regno ())
-+ if (ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 && !ii.get_dst_intval () && !ii.get_dst_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () && ii.get_src_regno () != ii.get_dst_mem_regno ())
- change_count += try_auto_inc (index, ii, ii.get_dst_mem_reg ());
-
- }
-@@ -4462,19 +4467,18 @@ namespace
- if (ispicref)
- {
- rtx dest = SET_DEST(set);
-- if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC
-- )
-+ if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC)
- {
- // split the insn
- rtx reg = gen_reg_rtx (Pmode);
-
- rtx pat0 = gen_rtx_SET(reg, *src);
- //rtx_insn * n0 =
-- emit_insn_before(pat0, insn);
-+ emit_insn_before (pat0, insn);
-
- rtx pat1 = gen_rtx_SET(dest, reg);
- //rtx_insn * n1 =
-- emit_insn_before(pat1, insn);
-+ emit_insn_before (pat1, insn);
-
- SET_INSN_DELETED(insn);
- }
-
-From 34ff5f41808c0f6eef3ea36cb6592f696b568e0f Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Fri, 1 Dec 2017 20:33:49 +0100
-Subject: [PATCH 268/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 4aee726e0fe2..5ca5b245f261 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171129-195545
-+20171201-203349
-
-From 865d8c2a52ee44716669dc3353d5cd10f2cc2836 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 3 Dec 2017 23:15:02 +0100
-Subject: [PATCH 269/303] fix opt_auto_inc if set is 0
-
----
- gcc/bbb-opts.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 7c8fc94ed8a6..757cc93dda94 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -845,6 +845,9 @@ insn_info::make_post_inc (int regno)
-
- // convert into POST_INC
- rtx set0 = single_set (new_insn);
-+ if (!set0)
-+ return false;
-+
- rtx set = set0;
-
- if (is_compare ())
-
-From d565753800ac3d71d6367a3c5f7db440b2068e48 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sun, 3 Dec 2017 23:43:43 +0100
-Subject: [PATCH 270/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 5ca5b245f261..e90d802ff727 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171201-203349
-+20171203-234342
-
-From 7018006ca506699e3241293713bca07d71bea88c Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 10 Dec 2017 16:00:32 +0100
-Subject: [PATCH 271/303] more baserel fixes + cleanup= less changes to
- original code
-
----
- gcc/bbb-opts.c | 395 +++++++++++++++++++++++++++++------------
- gcc/config/m68k/amigaos.c | 76 ++++++--
- gcc/config/m68k/constraints.md | 8 +-
- gcc/config/m68k/m68k.c | 35 +++-
- gcc/config/m68k/m68k.md | 16 +-
- gcc/config/m68k/m68kamigaos.h | 19 +-
- gcc/final.c | 6 +
- gcc/passes.c | 2 +-
- 8 files changed, 390 insertions(+), 167 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 757cc93dda94..dca287181b3a 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -70,12 +70,20 @@
- #include "tree-pass.h"
- #include "conditions.h"
- #include "langhooks.h"
-+#include <vector>
-+#include <set>
-+#include <map>
-
- int be_very_verbose;
- bool be_verbose;
-
- extern struct lang_hooks lang_hooks;
-
-+static void
-+update_insn_infos (void);
-+static unsigned
-+track_regs ();
-+
- /* Lookup of the current function name. */
- extern tree current_function_decl;
- static tree last_function_decl;
-@@ -116,63 +124,210 @@ enum proepis
- IN_CODE, IN_PROLOGUE, IN_EPILOGUE, IN_EPILOGUE_PARALLEL_POP
- };
-
-+/**
-+ * What's needed to track values?
-+ */
- class track_var
- {
-- unsigned * indexes;
-- rtx * values;
-- unsigned * versions;
-+ rtx value[FIRST_PSEUDO_REGISTER];
-+ unsigned mask[FIRST_PSEUDO_REGISTER];
-+
-+ bool
-+ extend (rtx * z, unsigned * mask, machine_mode dstMode, rtx x)
-+ {
-+ switch (GET_CODE(x))
-+ {
-+ case CONST_INT:
-+ case CONST_FIXED:
-+ case CONST_DOUBLE:
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ /* these can be used directly. */
-+ *z = x;
-+ return true;
-+
-+ case REG:
-+ {
-+ rtx v = value[REGNO(x)];
-+ /* try to expand the register. */
-+ if (v)
-+ {
-+ if (GET_MODE(v) != VOIDmode && dstMode != GET_MODE(v))
-+ return false;
-+
-+ *mask |= mask[REGNO(x)];
-+ *z = value[REGNO(x)];
-+ return true;
-+ }
-+
-+ /* store the reg otherwise. */
-+ *mask |= (1 << REGNO(x));
-+ *z = x;
-+ return true;
-+ }
-+ case PLUS:
-+ case MINUS:
-+ // handle only in combination with const
-+ {
-+ rtx y = XEXP(x, 0);
-+ if (GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref(y))
-+ return false;
-+
-+ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant offset (later).
-+ *z = gen_rtx_PLUS(GET_MODE(x), y, XEXP(x, 1));
-+ else
-+ *z = gen_rtx_MINUS(GET_MODE(x), y, XEXP(x, 1));
-+ return true;
-+ }
-+
-+ /* memory reads. */
-+ case MEM:
-+ {
-+ rtx m = XEXP(x, 0);
-+ switch (GET_CODE(m))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ /* these can be used directly. */
-+ *z = x;
-+ return true;
-+
-+ case REG:
-+ if (!extend (&m, mask, dstMode, m))
-+ return false;
-+
-+ *z = gen_rtx_MEM (GET_MODE(x), m);
-+ return true;
-+
-+ case PLUS:
-+ case MINUS:
-+ // handle only in combination with const
-+ {
-+ rtx y = XEXP(m, 0);
-+ if (!REG_P(
-+ y) && GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref(y))
-+ return false;
-+
-+ if (REG_P(y))
-+ if (!extend (&y, mask, dstMode, y))
-+ return false;
-+
-+ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant offset (later).
-+ m = gen_rtx_PLUS(GET_MODE(m), y, XEXP(m, 1));
-+ else
-+ m = gen_rtx_MINUS(GET_MODE(m), y, XEXP(m, 1));
-+
-+ *z = gen_rtx_MEM (GET_MODE(x), m);
-+ return true;
-+ }
-+ }
-+ return false;
-+ }
-+
-+ default:
-+ return false;
-+ }
-+ }
-
- public:
-- track_var (track_var const * o = 0) :
-- indexes ((unsigned *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(unsigned))), values (
-- (rtx *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(rtx))), versions (
-- (unsigned *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof(unsigned)))
-+ track_var (track_var const * o = 0)
- {
- if (o)
- assign (o);
-+ else
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+
-+ rtx
-+ get (unsigned regno)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return 0;
-+
-+ return value[regno];
- }
-
- void
-- set (unsigned regno, unsigned index, rtx rtx, unsigned ver)
-+ set (machine_mode mode, unsigned regno, rtx x, unsigned index)
- {
- if (regno >= FIRST_PSEUDO_REGISTER)
- return;
-
-- indexes[regno] = index;
-- values[regno] = rtx;
-- versions[regno] = ver;
-+ if (!extend (&value[regno], &mask[regno], mode, x))
-+ {
-+ clear (regno, index);
-+ }
- }
-
-- unsigned
-- get_index (unsigned regno) const
-+ bool
-+ equals (unsigned regno, rtx x)
- {
- if (regno >= FIRST_PSEUDO_REGISTER)
-- return 0;
-- return indexes[regno];
-+ return false;
-+
-+ if (x == 0 || value[regno] == 0)
-+ return false;
-+
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (!extend (&z, &m, GET_MODE(x), x))
-+ return false;
-+
-+ return rtx_equal_p (z, value[regno]);
- }
-
-- rtx
-- get_value (unsigned regno) const
-+ void
-+ clear (unsigned regno, unsigned index)
- {
- if (regno >= FIRST_PSEUDO_REGISTER)
-- return 0;
-- return values[regno];
-+ return;
-+
-+ value[regno] = gen_rtx_CONST_INT (VOIDmode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
-+ mask[regno] = FIRST_PSEUDO_REGISTER;
- }
-
-- unsigned
-- get_version (unsigned regno) const
-+ void
-+ clear_aftercall (unsigned index)
- {
-- if (regno >= FIRST_PSEUDO_REGISTER)
-- return 0;
-- return versions[regno];
-+ for (int i = 2; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (mask[i])
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+ clear (0, index);
-+ clear (1, index);
-+ clear (8, index);
-+ clear (9, index);
- }
-
- void
-- assign (track_var const * o) const
-+ clear_for_mask (unsigned def, unsigned index)
- {
-- memcpy (indexes, o->indexes, FIRST_PSEUDO_REGISTER * sizeof(unsigned));
-- memcpy (values, o->values, FIRST_PSEUDO_REGISTER * sizeof(rtx));
-- memcpy (versions, o->versions, FIRST_PSEUDO_REGISTER * sizeof(unsigned));
-+ if (!def)
-+ return;
-+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-+ {
-+ // register changed or used somehow
-+ if ((1 << regno) & def)
-+ clear (regno, index);
-+ }
-+ }
-+
-+ void
-+ assign (track_var const * o)
-+ {
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ value[i] = o->value[i];
-+ mask[i] = o->mask[i];
-+ }
- }
- /* only keep common values in both sides. */
-@@ -181,8 +336,11 @@ class track_var
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (versions[i] != o->versions[0] || !rtx_equal_p (values[i], o->values[i]))
-- values[i] = o->values[i] = 0;
-+ if (!rtx_equal_p (value[i], o->value[i]))
-+ {
-+ value[i] = o->value[i] = 0;
-+ mask[i] = mask[i] = 0;
-+ }
- }
- }
+diff --git a/libiberty/lrealpath.c b/libiberty/lrealpath.c
+index b27c8de990e9..78c06e46da58 100644
+--- libiberty/lrealpath.c
++++ libiberty/lrealpath.c
+@@ -73,7 +73,7 @@ extern char *canonicalize_file_name (const char *);
+ #endif
-@@ -192,9 +350,8 @@ class track_var
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (versions[i] != o->versions[0] || !rtx_equal_p (values[i], o->values[i]))
-- if (values[i])
-- return false;
-+ if (!rtx_equal_p (value[i], o->value[i]))
-+ return false;
- }
- return true;
- }
-@@ -931,7 +1088,7 @@ insn_info::auto_inc_fixup (int regno, int size)
- SET_SRC(set) = XEXP(src, 0);
- }
- else
-- XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
-+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
- }
- else if (get_src_mem_regno () == regno)
- {
-@@ -1367,11 +1524,11 @@ update_insn2index ()
- static void
- update_label2jump ()
+ char *
+-lrealpath (const char *filename)
++__xlrealpath (const char *filename)
{
-+ update_insn2index ();
-+
- for (unsigned index = 0; index < infos.size (); ++index)
- {
- insn_info & ii = infos[index];
-- insn2info.insert (std::make_pair (ii.get_insn (), &ii));
--
- if (ii.is_label ())
- for (l2j_iterator i = label2jump.find (ii.get_insn ()->u2.insn_uid), k = i;
- i != label2jump.end () && i->first == k->first; ++i)
-@@ -1598,12 +1755,47 @@ is_reg_dead (unsigned regno, unsigned _pos)
- return true;
+ /* Method 1: The system has a compile time upper bound on a filename
+ path. Use that and realpath() to canonicalize the name. This is
+@@ -155,3 +155,19 @@ lrealpath (const char *filename)
+ /* This system is a lost cause, just duplicate the filename. */
+ return strdup (filename);
}
-
-+bool dump_reg_track;
-+void
-+append_reg_cache (FILE * f, rtx_insn * insn)
-+{
-+ i2i_iterator i = insn2info.find (insn);
-+ if (i == insn2info.end ())
-+ return;
+
-+ insn_info & jj = *i->second;
-+ unsigned index = jj.get_index ();
-+ if (index + 1 < infos.size ())
-+ ++index;
-+ insn_info & ii = infos[index];
-+
-+ track_var * track = ii.get_track_var ();
-+ if (track == 0)
-+ return;
-+
-+ fprintf (f, "\n");
-+
-+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-+ {
-+ rtx v = track->get (regno);
-+ if (v == 0)
-+ continue;
-+
-+// if (GET_CODE(v) == CONST_INT && GET_MODE(v) == VOIDmode)
-+// continue;
-+
-+ fprintf (f, "%s=", reg_names[regno]);
-+
-+ print_inline_rtx (f, v, 12);
-+ fprintf (f, "\n");
-+ }
-+}
-+
- /* helper stuff to enhance the asm output. */
- int my_flag_regusage;
- void
- append_reg_usage (FILE * f, rtx_insn * insn)
- {
--
- i2i_iterator i = insn2info.find (insn);
- if (i == insn2info.end ())
- return;
-@@ -3635,53 +3827,48 @@ opt_shrink_stack_frame (void)
-
- /* Update the insn_infos to 'know' the value for each register.
- *
-- * atm only assignments to registers are optimized.
-+ * assignments to registers are optimized by knowing the value. If the same value is assigned, omit that insn.
- *
-- * We track register aliases:
-+ * I'm tracking
- *
-- * ;10
-- * move.l 4(a0),d0
-+ * rtx - the value
- *
-- * ;15
-- * move.l d0,d1
-+ * mask - the referenced registers in the value, 0 means that rtx is const, with baserel a4 is not tracked
- *
-+ * if there is a value for the referenced register(s), the value is extended
- *
-- * ;18
-- * move.l d1,d2
-+ * e.g.
- *
-- * - results into d0 is an alias for d1 (and vice versa).
-- * - to identify if a register is still changed, we also track the line where it was assigned.
-- * - in addition to register aliases memory reads are tracked too for normal memory access (e.g. no auto inc)
-- * but not if the memory read is marked as volatile
-+ * ; line 2
-+ * move.l 12(a7),a0
- *
-- * E.g.
-+ * -> rtx = mem(plus(a7, 12)); 0x8000
- *
-- * d0[10]: 4(a0)[10]
-- * d1[15]: d0[10]
-- * d2[18]: d1[15]
-+ * ; line 10
-+ * move.l 4(a0),d0
- *
-- * with that information we know that d2[18] also contains 4(a0)[10]
-+ * -> rtx = mem(plus(mem(plus(a7, 12)), 4)); 0x8000; extended with value from a0, thus a7 is used only
- *
-- * info to track per register:
-- * line index where the value was assigned
-- * rtx which was assigned - or null if not a usable rtx
-- * reg line index - if rtx is a register
-+ * ;15
-+ * lea _label,a1
- *
-- * for each assignment which is not to a register the rtx are scanned and set to null on match
-+ * -> rtx = symbol_ref(_label) ; 0x0000 == const
- *
- * on jumps the current state is duplicated and merged at the given label
- *
- * on merge only identical info is kept, rest is discarded
- *
-- * for each insn first the track info for all defined regs is discarded before the new one is set.
-+ * for each insn for all defined regs the value and mask is discarded before a new value is set.
-+ *
-+ * for each insn which is writing to memory, all non const values are discarded.
- *
- *
-- * after the track info is complete, each insn is evaluated agains the track info.
-+ * after the track info is complete, each insn setting a register is evaluated against the track info.
- *
- * now redundant loads are found and eliminated
-- * also unused assignments are found an eliminated
- *
- */
-+
- static unsigned
- track_regs ()
- {
-@@ -3733,26 +3920,19 @@ track_regs ()
- ii.get_track_var ()->assign (track);
-
- int dregno = ii.get_dst_regno ();
-+ track->clear (dregno, index);
-+
- unsigned def = ii.get_def () & 0xffffff;
-- if (def)
-- {
-- for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-- {
-- // register changed or used somehow
-- if (((1 << regno) & def)
-- || (track->get_index (regno) && (infos[track->get_index (regno)].get_myuse () & def)))
-- track->set (regno, index, 0, index);
-- }
-- // clear on self update
-- if (def & ii.get_myuse ())
-- track->set (dregno, index, 0, index);
-- }
-+ track->clear_for_mask (def, index);
-
- if (ii.is_compare ())
- continue;
-
- if (ii.is_call ())
-- continue;
-+ {
-+ track->clear_aftercall (index);
-+ continue;
-+ }
-
- rtx set = single_set (ii.get_insn ());
-
-@@ -3786,21 +3966,7 @@ track_regs ()
- if (ii.is_src_mem () && src->volatil)
- continue;
-
-- // add the entry - determine the version - use 0 for const values
-- unsigned version;
-- if (GET_CODE(src) != CONST_INT && GET_CODE(src) != CONST_FIXED && GET_CODE(src) != CONST_DOUBLE)
-- {
-- if (ii.get_src_regno () >= 0)
-- version = track->get_index (ii.get_src_regno ());
-- else if (ii.get_src_mem_regno () >= 0)
-- version = track->get_index (ii.get_src_mem_regno ());
-- else
-- version = index;
-- }
-- else
-- version = 0;
--
-- track->set (dregno, index, src, version);
-+ track->set (ii.get_mode (), dregno, src, index);
- }
- delete track;
- }
-@@ -3843,35 +4009,23 @@ opt_elim_dead_assign (int blocked_regno)
- {
- track_var * track = ii.get_track_var ();
-
--// if (ii.get_src_regno() == 8 && ii.get_dst_regno() == 7)
--// printf("%d: move %d,%d: v=%d (%d->%d), i=%d (%d->%d)\n", index, ii.get_src_regno(), ii.get_dst_regno(),
--// track->get_version(ii.get_src_regno()), infos[track->get_version(ii.get_src_regno())].get_src_regno(), infos[track->get_version(ii.get_src_regno())].get_dst_regno(),
--// track->get_index(ii.get_dst_regno()), infos[track->get_index(ii.get_dst_regno())].get_src_regno(), infos[track->get_index(ii.get_dst_regno())].get_dst_regno());
--
- rtx src = SET_SRC(set);
-- if (rtx_equal_p (track->get_value (ii.get_dst_regno ()), src))
-+ if (track->equals (ii.get_dst_regno (), src))
- {
-- if ((REG_P(src) && track->get_version (ii.get_dst_regno ()) == track->get_index (ii.get_src_regno ()))
-- || !REG_P(src))
-- {
-- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-- SET_INSN_DELETED(insn);
-- ++change_count;
-- continue;
-- }
-+ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
- }
-- // check reverse assignment
-- if (REG_P(src))
-+
-+ if (ii.get_src_reg () && track->equals (ii.get_src_regno (), SET_DEST(set)))
- {
-- if (REG_P(src) && rtx_equal_p (track->get_value (ii.get_src_regno ()), SET_DEST(set))
-- && track->get_version (ii.get_src_regno ()) == track->get_index (ii.get_dst_regno ()))
-- {
-- log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-- SET_INSN_DELETED(insn);
-- ++change_count;
-- continue;
-- }
-+ log ("(e) %d: eliminate redundant reverse load to %s\n", index, reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
- }
-+
- }
- }
- return change_count;
-@@ -4300,6 +4454,7 @@ namespace
- unsigned
- pass_bbb_optimizations::execute_bbb_optimizations (void)
- {
-+ dump_reg_track = strchr (string_bbb_opts, 'R') != 0;
- be_very_verbose = strchr (string_bbb_opts, 'V') != 0;
- be_verbose = strchr (string_bbb_opts, 'v') != 0;
- if (be_verbose && be_very_verbose)
-@@ -4380,6 +4535,12 @@ namespace
- if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
- dump_insns ("bbb", strchr (string_bbb_opts, 'X'));
-
-+ if (dump_reg_track)
-+ {
-+ update_insns ();
-+ track_regs ();
-+ }
+
- return r;
- }
-
-@@ -4463,9 +4624,9 @@ namespace
- bool ispicref = false;
- // fix add PLUS/MINUS into the unspec offset
- if (GET_CODE(*src) == PLUS || GET_CODE(*src) == MINUS)
-- ispicref = CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(*src, 0));
-+ ispicref = amiga_is_const_pic_ref(XEXP(*src, 0));
- else
-- ispicref = CONST_PLUS_PIC_REG_CONST_UNSPEC_P(*src);
-+ ispicref = amiga_is_const_pic_ref(*src);
-
- if (ispicref)
- {
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index ba8a5d757d21..298bcb18300c 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -793,17 +793,47 @@ amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_U
- /**
- * Does x reference the pic_reg and is const or plus?
- */
-+static int
-+_amiga_is_const_pic_ref (const_rtx x)
++char *
++lrealpath (const char *filename)
+{
-+ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS)
++ char * r = __xlrealpath(filename);
++#if defined (_WIN32)
++ if (strncmp(r, "/cygdrive/", 10) == 0)
+ {
-+ if (GET_CODE(XEXP(x, 1)) == CONST_INT)
-+ return _amiga_is_const_pic_ref(XEXP(x, 0));
-+ return false;
++ r[9] = r[10];
++ r[10] = ':';
++ r = strdup(&r[9]);
+ }
-+
-+ if (GET_CODE(x) == CONST)
-+ x = XEXP(x, 0);
-+ if (GET_CODE(x) != PLUS)
-+ return false;
-+
-+ const_rtx reg = XEXP(x, 0);
-+ if (!REG_P(reg) && REGNO(reg) != PIC_REG)
-+ return false;
-+
-+ const_rtx unspec = XEXP(x, 1);
-+ while (GET_CODE(unspec) == PLUS || GET_CODE(unspec) == CONST)
-+ unspec = XEXP(unspec, 0);
-+
-+ if (GET_CODE(unspec) != UNSPEC)
-+ return false;
-+
-+ return true;
-+}
-+
- int
--amiga_is_const_pic_ref (const_rtx x)
-+amiga_is_const_pic_ref (const_rtx cnst)
- {
-- const_rtx y = x;
- if (flag_pic < 3)
-- return false;
-- while (GET_CODE(y) == CONST || GET_CODE(y) == PLUS)
-- y = XEXP(y, 0);
-- return (x != y && REG_P(y) && REGNO(y) == PIC_REG);
-+ return true;
-+ int r = _amiga_is_const_pic_ref (cnst);
-+// fprintf(stderr, r ? "valid pic: " : "invalid pic: ");
-+// debug_rtx(cnst);
++#endif
+ return r;
- }
-
-+
- /* 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.
-
-@@ -880,15 +910,27 @@ amigaos_legitimate_src (rtx src)
- if (flag_pic < 3)
- return true;
-
-+ if (MEM_P(src))
-+ {
-+ rtx x = XEXP(src, 0);
-+ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS) {
-+ if (amiga_is_const_pic_ref(XEXP(x, 0))
-+ || amiga_is_const_pic_ref(XEXP(x, 1)))
-+ return false;
-+ }
-+ return true;
-+ }
-+
- if (GET_CODE(src) == PLUS || GET_CODE(src) == MINUS)
- {
- rtx x = XEXP(src, 0);
-+ rtx y = XEXP(src, 1);
-
- /** handled in print_operand_address(...) */
-- if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x))
-- return true;
-+ if (amiga_is_const_pic_ref(x))
-+ return GET_CODE(y) == CONST_INT;
-
-- return amigaos_legitimate_src(x) && amigaos_legitimate_src(XEXP(src, 1));
-+ return amigaos_legitimate_src(x) && amigaos_legitimate_src(y) && !amiga_is_const_pic_ref(y);
- }
-
- if (GET_CODE(src) == CONST)
-@@ -903,16 +945,12 @@ amigaos_legitimate_src (rtx src)
- if (!REG_P(reg))
- return true;
-
--// debug_rtx(src);
- return false;
- }
- }
-
- if (GET_CODE(op) == UNSPEC)
-- {
--// debug_rtx(src);
-- return false;
-- }
-+ return false;
- }
-
- return true;
-@@ -986,3 +1024,13 @@ amigaos_alternate_frame_setup (int fsize)
- #endif
- }
-
-+#if 0
-+extern bool debug_recog(char const * txt, int which_alternative, int n, rtx * operands)
-+{
-+ fprintf(stderr, "%s: %d ", txt, which_alternative);
-+ for (int i = 0; i < n; ++i)
-+ print_rtl(stderr, operands[i]);
-+ fprintf(stderr, "\n--\n");
-+ return true;
+}
-+#endif
-diff --git a/gcc/config/m68k/constraints.md b/gcc/config/m68k/constraints.md
-index 0d9b1b69ab18..1223852570c1 100644
---- gcc/config/m68k/constraints.md
-+++ gcc/config/m68k/constraints.md
-@@ -1,5 +1,5 @@
- ;; Constraint definitions for m68k
--;; Copyright (C) 2007-2016 Free Software Foundation, Inc.
-+;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
-
- ;; This file is part of GCC.
-
-@@ -97,12 +97,6 @@
- (match_test "!TARGET_PCREL")
- (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
-
--(define_constraint "t"
-- "Used for operands that satisfy 's' without PIC stuff, when -mpcrel is not in effect."
-- (and (match_code "symbol_ref,label_ref,const")
-- (match_test "!TARGET_PCREL")
-- (match_test "!flag_pic || !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(op)")))
--
- (define_memory_constraint "Q"
- "Means address register indirect addressing mode."
- (and (match_code "mem")
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index f5daa0cbcc26..a655ed8476bb 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -2176,8 +2176,10 @@ m68k_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
- /* SBF: the baserel(32) const plus pic_ref, symbol is an address. */
- if (amiga_is_const_pic_ref(x))
- return true;
-+
- if (!amigaos_legitimate_src(x))
- return false;
-+
- #endif
-
- return m68k_decompose_address (mode, x, strict_p, &address);
-@@ -2530,7 +2532,7 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- /* SBF: Does the symbol use common or bss and qualifies for pic_reg?
- * Do not ref to .text via pic_reg!
- */
-- if (!SYMBOL_REF_FUNCTION_P(orig) && decl && (DECL_COMMON (decl) || bss_initializer_p (decl)))
-+ if (GET_CODE (orig) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P(orig) && decl && (DECL_COMMON (decl) || bss_initializer_p (decl)))
- {
- /* SBF: unfortunately using the wrapped symbol without MEM does not work.
- * The pic_ref reference gets decomposed and leads to no working code.
-@@ -4603,7 +4605,7 @@ print_operand (FILE *file, rtx op, int letter)
- && INTVAL (XEXP (op, 0)) >= -0x8000)
- #ifdef TARGET_AMIGA
- /* SBF: Do not append some 'l' with baserel(32). */
-- && !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(op, 0))
-+ && !amiga_is_const_pic_ref(XEXP(op, 0))
- #endif
- )
- fprintf (file, MOTOROLA ? ".l" : ":l");
-@@ -4830,12 +4832,35 @@ print_operand_address (FILE *file, rtx addr)
- /*
- * SBF: remove the const wrapper.
- */
-- if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(addr))
-+ if (amiga_is_const_pic_ref(addr))
- {
-- print_operand_address(file, XEXP(addr, 0));
-+ /* handle (plus (unspec ) (const_int) */
-+ rtx *x = &addr;
-+ while (GET_CODE(*x) != PLUS)
-+ x = &XEXP(*x, 0);
-+
-+ x = &XEXP(*x, 1); // CONST
-+ if (GET_CODE(*x) == CONST)
-+ x = &XEXP(*x, 0);
-+
-+ /* if there is a plus - swap it.
-+ * we want n+symbol:W (not symbol:W+n)
-+ */
-+ if (GET_CODE(*x) == PLUS)
-+ {
-+ rtx plus = *x;
-+ fprintf (file, "%d+", (int) INTVAL (XEXP(plus, 1)));
-+
-+ *x = XEXP(plus, 0);
-+ print_operand_address(file, XEXP(addr, 0));
-+ *x = plus;
-+ }
-+ else
-+ print_operand_address(file, XEXP(addr, 0));
-+
- return;
- }
-- if (GET_CODE(addr) == PLUS && CONST_PLUS_PIC_REG_CONST_UNSPEC_P(XEXP(addr, 0)))
-+ if (GET_CODE(addr) == PLUS && amiga_is_const_pic_ref(XEXP(addr, 0)))
- {
- fprintf (file, "%d+", (int) INTVAL (XEXP(addr, 1)));
- print_operand_address(file, XEXP(XEXP(addr, 0),0));
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index 7b6f69835d10..05ef02027f01 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -500,7 +500,7 @@
- [(set (cc0)
- (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mr,ma,>")
- (match_operand:SI 1 "general_operand" "mr,ma,KTr,Ksr,>")))]
-- "!TARGET_COLDFIRE && (flag_pic < 3 || GET_CODE(operands[1]) != CONST || GET_CODE(XEXP(operands[1], 0)) != PLUS || !REG_P(XEXP(XEXP(operands[1], 0), 0)) || REGNO(XEXP(XEXP(operands[1], 0), 0)) != PIC_REG)"
-+ "!TARGET_COLDFIRE"
- {
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- return "cmpm%.l %1,%0";
-@@ -955,8 +955,8 @@
- (define_insn "*movsi_m68k"
- ;; Notes: make sure no alternative allows g vs g.
- ;; We don't allow f-regs since fixed point cannot go in them.
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=g,a,d,a<")
-- (match_operand:SI 1 "general_src_operand" "damSnt,T,n,i"))]
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
-+ (match_operand:SI 1 "general_src_operand" "damSnT,n,i"))]
- "!TARGET_COLDFIRE && reload_completed"
- {
- return output_move_simode (operands);
-@@ -966,8 +966,8 @@
- ;; force integer constants in range for a moveq to be reloaded
- ;; if they are headed for memory.
- (define_insn "*movsi_m68k2"
-- [(set (match_operand:SI 0 "nonimmediate_operand" "=g,a,d,a<")
-- (match_operand:SI 1 "general_src_operand" "damSKt,T,n,i"))]
-+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
-+ (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))]
-
- "!TARGET_COLDFIRE"
- {
-@@ -2468,7 +2468,7 @@
- (define_insn "*addsi3_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a")
- (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
-- (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLt,mSrIKLt")))]
-+ (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
-
-
- "! TARGET_COLDFIRE"
-@@ -7090,8 +7090,6 @@
- operands[1] = gen_rtx_REG (Pmode, PIC_REG);
- return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
- }
-- else if (TARGET_AMIGAOS)
-- return "lea (%%pc, __GLOBAL_OFFSET_TABLE_), %0";
- else if (MOTOROLA)
- {
- if (TARGET_COLDFIRE)
-@@ -7215,7 +7213,7 @@
- && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
- && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
- && !valid_mov3q_const (INTVAL (operands[2])))
-- && !CONST_PLUS_PIC_REG_CONST_UNSPEC_P(operands[2])"
-+ && !amiga_is_const_pic_ref(operands[2])"
- [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
- (set (match_dup 1) (match_dup 2))]
- {
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 0e982c12da9c..43ffcd0add39 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -700,18 +700,17 @@ extern int amiga_is_const_pic_ref(const_rtx x);
- ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
- || GET_CODE (X) == HIGH \
-- ) && !amiga_is_const_pic_ref(X))
-+ ))
-+
-
-
- /* 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))
-+ ! symbolic_operand (X, VOIDmode) && \
-+ ! amiga_is_const_pic_ref(X))
-
- // (GET_CODE(X) == CONST && (GET_CODE(XEXP(X, 0)) == SYMBOL_REF || GET_CODE(XEXP(X, 0)) == LABEL_REF) && !CONSTANT_POOL_ADDRESS_P (XEXP(X, 0))) ||
-
-@@ -742,12 +741,4 @@ extern int amiga_is_const_pic_ref(const_rtx x);
- extern int
- amigaos_function_arg_reg(unsigned regno);
-
--/* SBF: macro to test for const via pic_reg. */
--#define CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x) \
-- (GET_CODE(x) == CONST \
-- && GET_CODE(XEXP(x, 0)) == PLUS \
-- && REG_P(XEXP(XEXP(x, 0), 0)) \
-- && REGNO(XEXP(XEXP(x, 0), 0)) == PIC_REG \
-- && GET_CODE(XEXP(XEXP(x, 0), 1)) == CONST \
-- && GET_CODE(XEXP(XEXP(XEXP(x, 0), 1), 0)) == UNSPEC \
-- )
-+//extern bool debug_recog(char const * txt, int which_alternative, int n, rtx * operands);
-diff --git a/gcc/final.c b/gcc/final.c
-index 009d8eca6baf..fa8b2964a40d 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -3626,6 +3626,10 @@ output_asm_insn (const char *templ, rtx *operands)
- {
- extern bool be_very_verbose;
- extern void append_reg_usage(FILE *, rtx_insn *);
-+
-+ extern bool dump_reg_track;
-+ void append_reg_cache (FILE * f, rtx_insn * insn);
-+
- const char *p;
- int c;
- #ifdef ASSEMBLER_DIALECT
-@@ -3784,6 +3788,8 @@ output_asm_insn (const char *templ, rtx *operands)
-
- if (be_very_verbose)
- append_reg_usage(asm_out_file, current_insn);
-+ if (dump_reg_track)
-+ append_reg_cache(asm_out_file, current_insn);
-
- /* Write out the variable names for operands, if we know them. */
- if (flag_verbose_asm)
-diff --git a/gcc/passes.c b/gcc/passes.c
-index b216ee028245..1d53bb23b1b0 100644
---- gcc/passes.c
-+++ gcc/passes.c
-@@ -2284,7 +2284,7 @@ void dump_insns(char const * name)
- if (!set)
- continue;
-
-- if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(SET_SRC(set)) && MEM_P(SET_DEST(set)))
-+ if (amiga_is_const_pic_ref(SET_SRC(set)) && MEM_P(SET_DEST(set)))
- debug_rtx(insn);
- }
- #endif
-
-From 219a2963be09c8bf789e875cefc55520a195d44a Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 10 Dec 2017 21:04:22 +0100
-Subject: [PATCH 272/303] fix flag_pic handling
-
----
- gcc/config/m68k/amigaos.c | 2 +-
- gcc/config/m68k/m68k.c | 2 ++
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 298bcb18300c..1fe7d09b0142 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -826,7 +826,7 @@ int
- amiga_is_const_pic_ref (const_rtx cnst)
- {
- if (flag_pic < 3)
-- return true;
-+ return false;
- int r = _amiga_is_const_pic_ref (cnst);
- // fprintf(stderr, r ? "valid pic: " : "invalid pic: ");
- // debug_rtx(cnst);
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index a655ed8476bb..0a67f320bc1d 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -2173,6 +2173,8 @@ m68k_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
- struct m68k_address address;
-
- #ifdef TARGET_AMIGA
-+ if (MEM_P(x))
-+ return false;
- /* SBF: the baserel(32) const plus pic_ref, symbol is an address. */
- if (amiga_is_const_pic_ref(x))
- return true;
-
-From 4c1164092dea34f47a66606c8962bc9b053ed650 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sun, 10 Dec 2017 21:47:42 +0100
-Subject: [PATCH 273/303] fix mode handling in register tracking
-
----
- gcc/bbb-opts.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index dca287181b3a..32ef3ddde253 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -142,6 +142,8 @@ class track_var
- case CONST_DOUBLE:
- case SYMBOL_REF:
- case LABEL_REF:
-+ if (GET_MODE(x) != dstMode)
-+ return false;
- /* these can be used directly. */
- *z = x;
- return true;
-@@ -152,7 +154,7 @@ class track_var
- /* try to expand the register. */
- if (v)
- {
-- if (GET_MODE(v) != VOIDmode && dstMode != GET_MODE(v))
-+ if (dstMode != GET_MODE(v))
- return false;
-
- *mask |= mask[REGNO(x)];
-@@ -286,7 +288,7 @@ class track_var
- if (regno >= FIRST_PSEUDO_REGISTER)
- return;
-
-- value[regno] = gen_rtx_CONST_INT (VOIDmode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
-+ value[regno] = gen_rtx_CONST_INT (SImode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
- mask[regno] = FIRST_PSEUDO_REGISTER;
- }
-
-
-From 50f74c0693d7b285ec06e3d0b12d0acb5a966a2d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 11 Dec 2017 09:18:02 +0100
-Subject: [PATCH 274/303] fix compare handling in register tracking
-
----
- gcc/bbb-opts.c | 14 ++++++--------
- 1 file changed, 6 insertions(+), 8 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 32ef3ddde253..faf69739db8d 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -142,8 +142,6 @@ class track_var
- case CONST_DOUBLE:
- case SYMBOL_REF:
- case LABEL_REF:
-- if (GET_MODE(x) != dstMode)
-- return false;
- /* these can be used directly. */
- *z = x;
- return true;
-@@ -154,7 +152,7 @@ class track_var
- /* try to expand the register. */
- if (v)
- {
-- if (dstMode != GET_MODE(v))
-+ if (dstMode != GET_MODE(v) && GET_CODE(v) != CONST_INT)
- return false;
-
- *mask |= mask[REGNO(x)];
-@@ -289,7 +287,7 @@ class track_var
- return;
-
- value[regno] = gen_rtx_CONST_INT (SImode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
-- mask[regno] = FIRST_PSEUDO_REGISTER;
-+ mask[regno] = 1<<FIRST_PSEUDO_REGISTER;
- }
-
- void
-@@ -297,7 +295,7 @@ class track_var
- {
- for (int i = 2; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (mask[i])
-+ if (mask[i] && mask[i] < 1<<FIRST_PSEUDO_REGISTER)
- {
- value[i] = 0;
- mask[i] = 0;
-@@ -3921,15 +3919,15 @@ track_regs ()
- ii.mark_visited ();
- ii.get_track_var ()->assign (track);
-
-+ if (ii.is_compare ())
-+ continue;
-+
- int dregno = ii.get_dst_regno ();
- track->clear (dregno, index);
-
- unsigned def = ii.get_def () & 0xffffff;
- track->clear_for_mask (def, index);
-
-- if (ii.is_compare ())
-- continue;
--
- if (ii.is_call ())
- {
- track->clear_aftercall (index);
-
-From ed451fd6c28cdbca52f247c6719996a3b612c207 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 11 Dec 2017 10:13:33 +0100
-Subject: [PATCH 275/303] fix mode handling b/w/l
-
----
- gcc/bbb-opts.c | 30 +++++++++++++++++-------------
- 1 file changed, 17 insertions(+), 13 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index faf69739db8d..676201619747 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -149,20 +149,24 @@ class track_var
- case REG:
- {
- rtx v = value[REGNO(x)];
-+ unsigned mr = mask[REGNO(x)];
- /* try to expand the register. */
- if (v)
- {
-- if (dstMode != GET_MODE(v) && GET_CODE(v) != CONST_INT)
-+ if (dstMode != GET_MODE(v) && (GET_CODE(v) != CONST_INT || mr == (1<<FIRST_PSEUDO_REGISTER)))
- return false;
-
-- *mask |= mask[REGNO(x)];
-- *z = value[REGNO(x)];
-+ *mask |= mr;
-+ *z = v;
- return true;
- }
-
- /* store the reg otherwise. */
- *mask |= (1 << REGNO(x));
-- *z = x;
-+ if (GET_MODE(x) == dstMode)
-+ *z = x;
-+ else
-+ *z = gen_rtx_REG(dstMode, REGNO(x));
- return true;
- }
- case PLUS:
-@@ -259,7 +263,7 @@ class track_var
-
- if (!extend (&value[regno], &mask[regno], mode, x))
- {
-- clear (regno, index);
-+ clear (mode, regno, index);
- }
- }
-
-@@ -281,12 +285,12 @@ class track_var
- }
-
- void
-- clear (unsigned regno, unsigned index)
-+ clear (machine_mode mode, unsigned regno, unsigned index)
- {
- if (regno >= FIRST_PSEUDO_REGISTER)
- return;
-
-- value[regno] = gen_rtx_CONST_INT (SImode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
-+ value[regno] = gen_rtx_CONST_INT (mode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
- mask[regno] = 1<<FIRST_PSEUDO_REGISTER;
- }
-
-@@ -301,10 +305,10 @@ class track_var
- mask[i] = 0;
- }
- }
-- clear (0, index);
-- clear (1, index);
-- clear (8, index);
-- clear (9, index);
-+ clear (SImode, 0, index);
-+ clear (SImode, 1, index);
-+ clear (SImode, 8, index);
-+ clear (SImode, 9, index);
- }
-
- void
-@@ -316,7 +320,7 @@ class track_var
- {
- // register changed or used somehow
- if ((1 << regno) & def)
-- clear (regno, index);
-+ clear (SImode, regno, index);
- }
- }
-
-@@ -3923,7 +3927,7 @@ track_regs ()
- continue;
-
- int dregno = ii.get_dst_regno ();
-- track->clear (dregno, index);
-+ track->clear (ii.get_mode(), dregno, index);
-
- unsigned def = ii.get_def () & 0xffffff;
- track->clear_for_mask (def, index);
-
-From dfad986c2f43b33e98dbc2b70a4058b8cf771a37 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 11 Dec 2017 10:52:23 +0100
-Subject: [PATCH 276/303] fix mode handling
-
----
- gcc/bbb-opts.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 676201619747..e56e38ba73e0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -290,7 +290,7 @@ class track_var
- if (regno >= FIRST_PSEUDO_REGISTER)
- return;
-
-- value[regno] = gen_rtx_CONST_INT (mode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
-+ value[regno] = gen_rtx_raw_CONST_INT (mode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
- mask[regno] = 1<<FIRST_PSEUDO_REGISTER;
- }
-
-
-From 4e20f18ef084146dab3f58a73e4959c2ee85980f Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 11 Dec 2017 11:29:39 +0100
-Subject: [PATCH 277/303] treat SFmode as SImode for normal regs
-
----
- gcc/bbb-opts.c | 26 +++++++++++++++-----------
- 1 file changed, 15 insertions(+), 11 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index e56e38ba73e0..f54fb54d4405 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -153,7 +153,7 @@ class track_var
- /* try to expand the register. */
- if (v)
- {
-- if (dstMode != GET_MODE(v) && (GET_CODE(v) != CONST_INT || mr == (1<<FIRST_PSEUDO_REGISTER)))
-+ if (dstMode != GET_MODE(v) && (GET_CODE(v) != CONST_INT || mr == (1 << FIRST_PSEUDO_REGISTER)))
- return false;
-
- *mask |= mr;
-@@ -166,7 +166,7 @@ class track_var
- if (GET_MODE(x) == dstMode)
- *z = x;
- else
-- *z = gen_rtx_REG(dstMode, REGNO(x));
-+ *z = gen_rtx_REG (dstMode, REGNO(x));
- return true;
- }
- case PLUS:
-@@ -174,7 +174,7 @@ class track_var
- // handle only in combination with const
- {
- rtx y = XEXP(x, 0);
-- if (GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref(y))
-+ if (GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref (y))
- return false;
-
- if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant offset (later).
-@@ -208,8 +208,7 @@ class track_var
- // handle only in combination with const
- {
- rtx y = XEXP(m, 0);
-- if (!REG_P(
-- y) && GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref(y))
-+ if (!REG_P(y) && GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF && amiga_is_const_pic_ref (y))
- return false;
-
- if (REG_P(y))
-@@ -261,6 +260,9 @@ class track_var
- if (regno >= FIRST_PSEUDO_REGISTER)
- return;
-
-+ if (mode == SFmode && regno < 16)
-+ mode = SImode;
-+
- if (!extend (&value[regno], &mask[regno], mode, x))
- {
- clear (mode, regno, index);
-@@ -290,8 +292,10 @@ class track_var
- if (regno >= FIRST_PSEUDO_REGISTER)
- return;
-
-- value[regno] = gen_rtx_raw_CONST_INT (mode, 0x100000000000000LL | ((long long int) (regno) << 32) | index);
-- mask[regno] = 1<<FIRST_PSEUDO_REGISTER;
-+ if (mode == SFmode && regno < 16)
-+ mode = SImode;
-+ value[regno] = gen_rtx_raw_CONST_INT(mode, 0x100000000000000LL | ((long long int ) (regno) << 32) | index);
-+ mask[regno] = 1 << FIRST_PSEUDO_REGISTER;
- }
-
- void
-@@ -299,7 +303,7 @@ class track_var
- {
- for (int i = 2; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (mask[i] && mask[i] < 1<<FIRST_PSEUDO_REGISTER)
-+ if (mask[i] && mask[i] < 1 << FIRST_PSEUDO_REGISTER)
- {
- value[i] = 0;
- mask[i] = 0;
-@@ -3927,7 +3931,7 @@ track_regs ()
- continue;
-
- int dregno = ii.get_dst_regno ();
-- track->clear (ii.get_mode(), dregno, index);
-+ track->clear (ii.get_mode (), dregno, index);
-
- unsigned def = ii.get_def () & 0xffffff;
- track->clear_for_mask (def, index);
-@@ -4628,9 +4632,9 @@ namespace
- bool ispicref = false;
- // fix add PLUS/MINUS into the unspec offset
- if (GET_CODE(*src) == PLUS || GET_CODE(*src) == MINUS)
-- ispicref = amiga_is_const_pic_ref(XEXP(*src, 0));
-+ ispicref = amiga_is_const_pic_ref (XEXP(*src, 0));
- else
-- ispicref = amiga_is_const_pic_ref(*src);
-+ ispicref = amiga_is_const_pic_ref (*src);
-
- if (ispicref)
- {
-
-From b9eb7c80c772836b151ec2ae333c15d1ea744e18 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Mon, 11 Dec 2017 12:06:10 +0100
-Subject: [PATCH 278/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index e90d802ff727..a8c69c9addb5 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171203-234342
-+20171211-120610
-
-From 7b5b41278acb1bf3ca163b4adab55c08994cea6d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Mon, 11 Dec 2017 23:26:17 +0100
-Subject: [PATCH 279/303] do not use hoist with -Os use also pre
-
----
- gcc/gcse.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/gcc/gcse.c b/gcc/gcse.c
-index 5b2c96ecb5a6..f74e733f9337 100644
---- gcc/gcse.c
-+++ gcc/gcse.c
-@@ -4075,7 +4075,9 @@ pass_rtl_pre::gate (function *fun)
- {
- return optimize > 0 && flag_gcse
- && !fun->calls_setjmp
-+#ifndef TARGET_AMIGA
- && optimize_function_for_speed_p (fun)
-+#endif
- && dbg_cnt (pre);
- }
-
-@@ -4118,6 +4120,9 @@ class pass_rtl_hoist : public rtl_opt_pass
- bool
- pass_rtl_hoist::gate (function *)
- {
-+#ifdef TARGET_AMIGA
-+ return false;
-+#else
- return optimize > 0 && flag_gcse
- && !cfun->calls_setjmp
- /* It does not make sense to run code hoisting unless we are optimizing
-@@ -4125,6 +4130,7 @@ pass_rtl_hoist::gate (function *)
- bigger if we did PRE (when optimizing for space, we don't run PRE). */
- && optimize_function_for_size_p (cfun)
- && dbg_cnt (hoist);
-+#endif
- }
-
- } // anon namespace
-
-From 96f443e1846b944a8a665d0408574691dcca3259 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 12 Dec 2017 18:25:13 +0100
-Subject: [PATCH 280/303] fix g++ executable dependency to install-cpp
-
----
- gcc/Makefile.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/Makefile.in b/gcc/Makefile.in
-index 2871c5794c4b..4aedf54bab12 100644
---- gcc/Makefile.in
-+++ gcc/Makefile.in
-@@ -3271,7 +3271,7 @@ endif
- install-strip: install
-
- # Handle cpp installation.
--install-cpp: installdirs cpp$(exeext)
-+install-cpp: installdirs cpp$(exeext) all.cross
- -if test "$(enable_as_accelerator)" != "yes" ; then \
- rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
-
-From d42099d1dc94abdec1291e32149c77e2ec1533d0 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 12 Dec 2017 18:25:57 +0100
-Subject: [PATCH 281/303] fix handling SIGN_EXTEND in opt_auto_inc
-
----
- gcc/bbb-opts.c | 2 +-
- gcc/config/m68k/amigaos.c | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index f54fb54d4405..585e719c2d5c 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1021,7 +1021,7 @@ insn_info::make_post_inc (int regno)
-
- if (src_op && get_src_mem_regno () == regno)
- {
-- if (src_op == NEG || src_op == NOT)
-+ if (src_op == NEG || src_op == NOT || src_op == SIGN_EXTEND)
- mem = XEXP(mem, 0);
- else
- mem = XEXP(mem, 1);
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 1fe7d09b0142..60779c6579fc 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -939,7 +939,7 @@ amigaos_legitimate_src (rtx src)
- if (GET_CODE(op) == MINUS || GET_CODE(op) == PLUS)
- {
- rtx x = XEXP(op, 0);
-- if (GET_CODE(x) == NOT || GET_CODE(x) == NEG)
-+ if (GET_CODE(x) == NOT || GET_CODE(x) == NEG || GET_CODE(x) == SIGN_EXTEND)
- {
- rtx reg = XEXP(x, 0);
- if (!REG_P(reg))
-
-From c7ef0dc43dc68aebf4d27df6749c3a09b054d6e0 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Tue, 12 Dec 2017 19:07:22 +0100
-Subject: [PATCH 282/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index a8c69c9addb5..8f1a6c8420aa 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171211-120610
-+20171212-190722
-
-From 8b8789f06d99d60e60727b5a51690538d6dc403d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 19 Dec 2017 16:51:50 +0100
-Subject: [PATCH 283/303] do not deduplicate jump tables with 68000 since the 8
- bits pcrel offset might be to small
-
----
- gcc/cfgcleanup.c | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
-index 6e92d4cdde22..fddd9dd25458 100644
---- gcc/cfgcleanup.c
-+++ gcc/cfgcleanup.c
-@@ -2001,6 +2001,14 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- {
- rtx_insn *insn;
-
-+#ifdef TARGET_AMIGA
-+ /*
-+ * we need replicated labels, if the labels are too far away,
-+ * since on 68000 there are only 8 bits for the offset.
-+ */
-+ if (TARGET_68020 || TARGET_68040)
-+#endif
-+
- /* Replace references to LABEL1 with LABEL2. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
-@@ -2016,8 +2024,12 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- /* Avoid splitting if possible. We must always split when SRC2 has
- EH predecessor edges, or we may end up with basic blocks with both
- normal and EH predecessor edges. */
-- if (newpos2 == BB_HEAD (src2)
-+ if ((newpos2 == BB_HEAD (src2)
- && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
-+#ifdef TARGET_AMIGA
-+ || (!TARGET_68020 && !TARGET_68040)
-+#endif
-+ )
- redirect_to = src2;
- else
- {
-
-From 8a91b7265bab01a1011c8f153323732d9eee48cf Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Tue, 19 Dec 2017 18:34:20 +0100
-Subject: [PATCH 284/303] fix last patch
-
----
- gcc/cfgcleanup.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
-index fddd9dd25458..378b1fc595bb 100644
---- gcc/cfgcleanup.c
-+++ gcc/cfgcleanup.c
-@@ -2006,7 +2006,8 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- * we need replicated labels, if the labels are too far away,
- * since on 68000 there are only 8 bits for the offset.
- */
-- if (TARGET_68020 || TARGET_68040)
-+ if (!TARGET_68020 && !TARGET_68040)
-+ return false;
- #endif
-
- /* Replace references to LABEL1 with LABEL2. */
-@@ -2026,9 +2027,6 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- normal and EH predecessor edges. */
- if ((newpos2 == BB_HEAD (src2)
- && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
--#ifdef TARGET_AMIGA
-- || (!TARGET_68020 && !TARGET_68040)
--#endif
- )
- redirect_to = src2;
- else
-
-From 490ff33de1b66b808166de62b512e321fb412918 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Tue, 19 Dec 2017 19:03:07 +0100
-Subject: [PATCH 285/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 8f1a6c8420aa..8426e3db7f19 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171212-190722
-+20171219-190306
-
-From 775d5c86463a8acca838702ce6e5e7d97a5ca102 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 21 Dec 2017 19:19:07 +0100
-Subject: [PATCH 286/303] support section switching and provide the current
- var_decl
-
----
- gcc/varasm.c | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
-diff --git a/gcc/varasm.c b/gcc/varasm.c
-index b65f29c13a46..8ead5ec3fcbb 100644
---- gcc/varasm.c
-+++ gcc/varasm.c
-@@ -252,7 +252,6 @@ get_unnamed_section (unsigned int flags, void (*callback) (const void *),
- sect->unnamed.callback = callback;
- sect->unnamed.data = data;
- sect->unnamed.next = unnamed_sections;
--
- unnamed_sections = sect;
- return sect;
- }
-@@ -2228,11 +2227,17 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
- else
- {
- /* Special-case handling of vtv comdat sections. */
-- if (sect->named.name
-+ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED && sect->named.name
- && (strcmp (sect->named.name, ".vtable_map_vars") == 0))
- handle_vtv_comdat_section (sect, decl);
- else
-- switch_to_section (sect);
-+ {
-+#ifdef TARGET_AMIGA
-+ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED)
-+ sect->named.decl = decl;
-+#endif
-+ switch_to_section (sect);
-+ }
- if (align > BITS_PER_UNIT)
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
- assemble_variable_contents (decl, name, dont_output_data);
-@@ -4962,7 +4967,7 @@ output_constructor_regular_field (oc_local_state *local)
- if each element has the proper size. */
- if (local->field != NULL_TREE || local->index != NULL_TREE)
- {
-- if (fieldpos > local->total_bytes)
-+ if (fieldpos >= local->total_bytes)
- {
- assemble_zeros (fieldpos - local->total_bytes);
- local->total_bytes = fieldpos;
-
-From 21ecb9edff4c412a373ff9c1d3cb0ddc1d2ffdb9 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 21 Dec 2017 19:23:02 +0100
-Subject: [PATCH 287/303] added support for __chip, __fast and __far attributes
-
----
- gcc/config/m68k/amigaos.c | 207 +++++++++++-------------------------------
- gcc/config/m68k/amigaos.h | 5 +-
- gcc/config/m68k/m68k.c | 7 +-
- gcc/config/m68k/m68kamigaos.h | 14 ++-
- 4 files changed, 72 insertions(+), 161 deletions(-)
-
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-index 60779c6579fc..28d20a980978 100644
---- gcc/config/m68k/amigaos.c
-+++ gcc/config/m68k/amigaos.c
-@@ -52,152 +52,6 @@
- //int amiga_declare_object;
-
- #if 0
--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 ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED,
-- 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_ELT(TYPE_SIZE (type), 1) == 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 ((MEM_READONLY_P (rtl) && !MEM_VOLATILE_P (rtl)
-- && (flag_pic<3 || (TREE_CODE (decl) == STRING_CST
-- )
-- || amigaos_put_in_text (decl)))
-- || (TREE_CODE (decl) == VAR_DECL
-- && DECL_SECTION_NAME (decl) != NULL))
-- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
-- }
-- }
--
--
--/* 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 (OPT_Wattributes, "`%s' attribute only applies to variables",
-- IDENTIFIER_POINTER (name));
-- *no_add_attrs = true;
-- }
--
-- return NULL_TREE;
-- }
-
- //----- from 68k.c start
-
-@@ -607,6 +461,31 @@ amigaos_comp_type_attributes (const_tree type1, const_tree type2)
- return 0;
-
- }
-+ else
-+ {
-+ tree attrs1 = TYPE_ATTRIBUTES(type1);
-+
-+ tree chip1 = lookup_attribute("chip", attrs1);
-+ tree fast1 = lookup_attribute("fast", attrs1);
-+ tree far1 = lookup_attribute("far", attrs1);
-+
-+ tree attrs2 = TYPE_ATTRIBUTES(type2);
-+
-+ tree chip2 = lookup_attribute("chip", attrs2);
-+ tree fast2 = lookup_attribute("fast", attrs2);
-+ tree far2 = lookup_attribute("far", attrs2);
-+
-+ if (chip1)
-+ return chip2 && !fast2 && !far2;
-+
-+ if (fast1)
-+ return !chip2 && fast2 && !far2;
-+
-+ if (far1)
-+ return !chip2 && !fast2 && far2;
-+
-+ return !chip2 && !fast2 && !far2;
-+ }
- return 1;
- }
- /* end-GG-local */
-@@ -689,7 +568,7 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRI
- }
- else
- {
-- if (is_attribute_p ("chip", name))
-+ if (is_attribute_p ("chip", name) || is_attribute_p ("fast", name) || is_attribute_p ("far", name))
- {
- // OK
- }
-@@ -707,6 +586,8 @@ amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags ATTRI
- }
-
- #define AMIGA_CHIP_SECTION_NAME ".datachip"
-+#define AMIGA_FAST_SECTION_NAME ".datafast"
-+#define AMIGA_FAR_SECTION_NAME ".datafar"
-
- void
- amiga_insert_attribute (tree decl, tree * attr)
-@@ -716,28 +597,37 @@ amiga_insert_attribute (tree decl, tree * attr)
-
- tree name = TREE_PURPOSE(*attr);
-
-- if (is_attribute_p("chip", name))
-+ if (is_attribute_p("chip", name) || is_attribute_p("far", name) || is_attribute_p("fast", name))
- {
- if (!TREE_TYPE(decl) == VAR_DECL)
- {
-- error ("`chip' attribute can only be specified for variables");
-+ error ("`%s' attribute can only be specified for variables", IDENTIFIER_POINTER(name));
- return;
- }
-
- if (! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
- {
-- error ("`chip' attribute cannot be specified for local variables");
-+ error ("`%s' attribute cannot be specified for local variables", IDENTIFIER_POINTER(name));
- return;
- }
-+
-+ char const * section_name;
-+ if (is_attribute_p("chip", name))
-+ section_name = AMIGA_CHIP_SECTION_NAME;
-+ else if (is_attribute_p("fast", name))
-+ section_name = AMIGA_FAST_SECTION_NAME;
-+ else if (is_attribute_p("far", name))
-+ section_name = AMIGA_FAR_SECTION_NAME;
-+
-+
- /* The decl may have already been given a section attribute from
- a previous declaration. Ensure they match. */
- if (DECL_SECTION_NAME (decl) == NULL)
-- warning (OPT_Wattributes, "`%s' attribute is not yet supported", IDENTIFIER_POINTER(name));
--// set_decl_section_name(decl, AMIGA_CHIP_SECTION_NAME);
-- else if (strcmp (DECL_SECTION_NAME (decl), AMIGA_CHIP_SECTION_NAME) )
-+ set_decl_section_name(decl, section_name);
-+ else if (strcmp (DECL_SECTION_NAME (decl), section_name) )
- {
- error_at (DECL_SOURCE_LOCATION(decl),
-- "`chip' attribute conflicts with previous declaration");
-+ "`%s' attribute conflicts with previous declaration", IDENTIFIER_POINTER(name));
- }
- }
- else
-@@ -763,11 +653,16 @@ amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *tota
- /* Output assembly to switch to section NAME with attribute FLAGS. */
- #ifndef TARGET_AMIGAOS_VASM
- extern void
--amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
-+amiga_named_section (const char *name, unsigned int flags, tree decl )
- {
-+ // only one code section - TODO: with amiga hunk this is no longer mandatory.
- if (0 == strncmp (".text", name, 5))
- name = ".text";
-- fprintf (asm_out_file, "\t%s\n", name);
-+
-+ if (0 == strncmp(".data", name, 5) && (!DECL_INITIAL (decl) || initializer_zerop (DECL_INITIAL (decl))))
-+ fprintf (asm_out_file, "\t.bss%s\n", name + 5);
-+ else
-+ fprintf (asm_out_file, "\t%s\n", name);
- }
- #else
- extern void
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-index 723c36969ad1..1b60ed633a3a 100644
---- gcc/config/m68k/amigaos.h
-+++ gcc/config/m68k/amigaos.h
-@@ -118,7 +118,8 @@ Boston, MA 02111-1307, USA. */
- N_("Do not restore a4 in all functions") }
-
-
--/* Support sections in chip memory, currently '.datachip' only. */
-+/* Support sections in chip, fast memory, currently '.datachip', '.datafast'
-+ * and '.datafar' to abs addressing with baserel. */
- extern void
- amiga_named_section (const char *name, unsigned int flags, tree decl);
-
-@@ -445,6 +446,8 @@ while (0)
- #define SUBTARGET_ATTRIBUTES \
- { "asmregs", 0, 0, false, false, false, 0, true }, \
- { "chip", 0, 0, false, true, false, amigaos_handle_type_attribute, false }, \
-+ { "fast", 0, 0, false, true, false, amigaos_handle_type_attribute, false }, \
-+ { "far", 0, 0, false, true, false, amigaos_handle_type_attribute, false }, \
- { "saveds", 0, 0, false, true, true, amigaos_handle_type_attribute, false }, \
- { "regparm", 1, 1, false, true, true, amigaos_handle_type_attribute,\
- true }, \
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 0a67f320bc1d..85ed75e9fce7 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -2534,8 +2534,13 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- /* SBF: Does the symbol use common or bss and qualifies for pic_reg?
- * Do not ref to .text via pic_reg!
- */
-- if (GET_CODE (orig) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P(orig) && decl && (DECL_COMMON (decl) || bss_initializer_p (decl)))
-+ char const * section = decl ? DECL_SECTION_NAME(decl) : 0;
-+ if (GET_CODE (orig) == SYMBOL_REF && !orig->frame_related && !SYMBOL_REF_FUNCTION_P(orig) && decl
-+ && !decl->common.typed.base.readonly_flag
-+ && !decl->decl_with_vis.in_text_section && !section)
- {
-+// fprintf(stderr, "(a4) for: %s\n", decl->decl_minimal.name->identifier.id.str);
-+
- /* SBF: unfortunately using the wrapped symbol without MEM does not work.
- * The pic_ref reference gets decomposed and leads to no working code.
- */
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-index 43ffcd0add39..83d1acb9d1e3 100644
---- gcc/config/m68k/m68kamigaos.h
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -227,13 +227,19 @@ amiga_declare_object = 0
- /* end of stuff from m68kv4.h */
-
- #ifndef TARGET_AMIGAOS_VASM
--#ifndef BSS_SECTION_ASM_OP
-+#undef BSS_SECTION_ASM_OP
- #define BSS_SECTION_ASM_OP "\t.bss"
--#endif
- #else
- #define BSS_SECTION_ASM_OP "\tsection\tbss"
- #endif
-
-+#ifndef TARGET_AMIGAOS_VASM
-+#undef DATA_SECTION_ASM_OP
-+#define DATA_SECTION_ASM_OP "\t.data"
+diff --git a/libobjc/configure b/libobjc/configure
+index 55fcc33dbe2d..a60258f422d8 100755
+--- libobjc/configure
++++ libobjc/configure
+@@ -7637,7 +7637,8 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
++ #lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
++ enable_shared=no
+ ;;
+ esac
+ ;;
+diff --git a/libobjc/objc/objc.h b/libobjc/objc/objc.h
+index 37391a446bb0..6c73f53290e8 100644
+--- libobjc/objc/objc.h
++++ libobjc/objc/objc.h
+@@ -52,7 +52,11 @@ extern "C" {
+ Important: this could change and we could switch to 'typedef bool
+ BOOL' in the future. Do not depend on the type of BOOL. */
+ #undef BOOL
++#ifdef AMIGA
++typedef short BOOL;
+#else
-+#define DATA_SECTION_ASM_OP "\tsection\tdata"
+ typedef unsigned char BOOL;
+#endif
-+
- #ifndef ASM_OUTPUT_ALIGNED_BSS
- #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
- asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
-@@ -252,6 +258,8 @@ amiga_declare_object = 0
- do \
- { \
- builtin_define ("__chip=__attribute__((__chip__))"); \
-+ builtin_define ("__fast=__attribute__((__fast__))"); \
-+ builtin_define ("__far=__attribute__((__far__))"); \
- builtin_define ("__saveds=__attribute__((__saveds__))"); \
- builtin_define ("__interrupt=__attribute__((__interrupt__))"); \
- builtin_define ("__stackext=__attribute__((__stackext__))"); \
-@@ -360,7 +368,7 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
- #undef ASM_SPEC
- #ifndef TARGET_AMIGAOS_VASM
- #define ASM_SPEC \
-- "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
-+ "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc} %{!msmall-code:-S}"
- #else
- #define ASM_SPEC \
- "-gas -esc -ldots -Fhunk -quiet %(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc}"
-
-From c28c2cf8d727bb5bd0a1e98e9c9ca5c56635420f Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Thu, 21 Dec 2017 19:50:03 +0100
-Subject: [PATCH 288/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 8426e3db7f19..2d76043c1dd3 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171219-190306
-+20171221-195003
-
-From 40681c48c17fade42d96ffc1f405c2cc25bd7527 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 23 Dec 2017 11:07:32 +0100
-Subject: [PATCH 289/303] access DECL stuff only if it is a SYMBOL_REF
-
----
- gcc/config/m68k/m68k.c | 7 +++----
- gcc/config/m68k/m68k.h | 4 ++--
- 2 files changed, 5 insertions(+), 6 deletions(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 85ed75e9fce7..d6accd3bfd8d 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -2529,17 +2529,16 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- #ifdef TARGET_AMIGA
- else
- {
-- tree decl = SYMBOL_REF_DECL (orig);
-
- /* SBF: Does the symbol use common or bss and qualifies for pic_reg?
- * Do not ref to .text via pic_reg!
- */
-- char const * section = decl ? DECL_SECTION_NAME(decl) : 0;
-- if (GET_CODE (orig) == SYMBOL_REF && !orig->frame_related && !SYMBOL_REF_FUNCTION_P(orig) && decl
-+ tree decl;
-+ if (GET_CODE (orig) == SYMBOL_REF && !orig->frame_related && !SYMBOL_REF_FUNCTION_P(orig)
-+ && (decl = SYMBOL_REF_DECL (orig)) && !(DECL_SECTION_NAME(decl))
- && !decl->common.typed.base.readonly_flag
- && !decl->decl_with_vis.in_text_section && !section)
- {
--// fprintf(stderr, "(a4) for: %s\n", decl->decl_minimal.name->identifier.id.str);
-
- /* SBF: unfortunately using the wrapped symbol without MEM does not work.
- * The pic_ref reference gets decomposed and leads to no working code.
-diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
-index 200f07ef63a4..6cdc635d4df3 100644
---- gcc/config/m68k/m68k.h
-+++ gcc/config/m68k/m68k.h
-@@ -620,11 +620,11 @@ __transfer_from_trampoline () \
-
- #define REGNO_OK_FOR_INDEX_P(REGNO) \
- (INT_REGNO_P (REGNO) \
-- || INT_REGNO_P (reg_renumber[REGNO]))
-+ || (reg_renumber && INT_REGNO_P (reg_renumber[REGNO])))
-
- #define REGNO_OK_FOR_BASE_P(REGNO) \
- (ADDRESS_REGNO_P (REGNO) \
-- || ADDRESS_REGNO_P (reg_renumber[REGNO]))
-+ || (reg_renumber && ADDRESS_REGNO_P (reg_renumber[REGNO])))
-
- #define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
- (INT_REGNO_P (REGNO) \
-
-From 8b9a647f47952ea1411a54e51f5406fb79a3e30d Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 23 Dec 2017 11:08:23 +0100
-Subject: [PATCH 290/303] more compatible way to apply register renaming
-
----
- gcc/bbb-opts.c | 64 ++++++++++++++++++----------------------------------------
- 1 file changed, 20 insertions(+), 44 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 585e719c2d5c..432c9bb4bbd3 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -1452,11 +1452,11 @@ copy_reg (rtx reg, int newregno)
- }
-
- /* Rename the register plus track all locs to undo these changes. */
--static void
--temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldregno, unsigned newregno)
-+static rtx
-+find_reg_by_no (rtx x, unsigned oldregno)
- {
- if (!x)
-- return;
-+ return 0;
-
- RTX_CODE code = GET_CODE(x);
-
-@@ -1469,27 +1469,25 @@ temp_reg_rename (std::vector<std::pair<rtx *, rtx> > & loc, rtx x, unsigned oldr
- if (REG_P(y))
- {
- if (REGNO(y) == oldregno)
-- {
-- rtx z = copy_reg (y, newregno);
-- loc.push_back (std::make_pair (&XEXP(x, i), y));
-- XEXP(x, i) = z;
-- }
-+ return y;
- }
- else
-- temp_reg_rename (loc, y, oldregno, newregno);
-+ {
-+ rtx r = find_reg_by_no (y, oldregno);
-+ if (r)
-+ return r;
-+ }
- }
- else if (fmt[i] == 'E')
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
- {
- rtx z = XVECEXP(x, i, j);
-- if (GET_CODE(z) == CLOBBER)
-- {
-- /* workaround for shared clobbers. */
-- XVECEXP(x, i, j) = z = gen_rtx_CLOBBER(GET_MODE(z), XEXP(z, 0));
-- }
-- temp_reg_rename (loc, z, oldregno, newregno);
-+ rtx r = find_reg_by_no(z, oldregno);
-+ if (r)
-+ return r;
- }
- }
-+ return 0;
- }
-
- /*
-@@ -2454,45 +2452,27 @@ opt_reg_rename (void)
-
- /* check the renamed insns. */
- std::vector<unsigned> positions;
-- std::vector<std::pair<rtx *, rtx> > locs;
-- std::vector<std::pair<rtx *, rtx> > patch;
-- bool ok = true;
--
-- for (std::set<unsigned>::iterator i = found.begin (); ok && i != found.end (); ++i)
-+ for (std::set<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
- {
- insn_info & rr = infos[*i];
- rtx_insn * insn = rr.get_insn ();
-
-- /* temp rename. */
-- temp_reg_rename (locs, PATTERN (insn), oldregno, newregno);
-- if (!locs.empty ())
-+ /* get rename locations. */
-+ rtx from = find_reg_by_no(PATTERN (insn), oldregno);
-+ if (from)
- {
-- if (insn_invalid_p (insn, 1))
-- ok = false;
--
-- /* undo temp change but keep loc and new register. */
-- for (std::vector<std::pair<rtx *, rtx> >::iterator j = locs.begin (); j != locs.end (); ++j)
-- {
-- patch.push_back (std::make_pair (j->first, *j->first));
-- *j->first = j->second;
-- }
-+ rtx to = gen_raw_REG(GET_MODE(from), newregno);
-+ validate_replace_rtx_group(from, to, insn);
-
- positions.push_back (*i);
-- locs.clear ();
- }
- }
-
-- if (!ok)
-- {
-- cancel_changes (0);
-- continue;
-- }
--
- if (!apply_change_group ())
- continue;
-
- log ("(r) opt_reg_rename %s -> %s (%d locs, start at %d)\n", reg_names[oldregno], reg_names[newregno],
-- patch.size (), index);
-+ positions.size (), index);
- if (be_verbose)
- {
-@@ -2502,10 +2482,6 @@ opt_reg_rename (void)
- fflush (stdout);
- }
-
-- /* apply all changes. */
-- for (std::vector<std::pair<rtx *, rtx> >::iterator j = patch.begin (); j != patch.end (); ++j)
-- *j->first = j->second;
--
- return 1;
- }
- }
-
-From 3b4383bb016fb3c48ee7fbc30a9737370dc7d56b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 23 Dec 2017 11:53:34 +0100
-Subject: [PATCH 291/303] fix compile error - uups
-
----
- gcc/config/m68k/m68k.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index d6accd3bfd8d..29e2e45df844 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -2537,7 +2537,7 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- if (GET_CODE (orig) == SYMBOL_REF && !orig->frame_related && !SYMBOL_REF_FUNCTION_P(orig)
- && (decl = SYMBOL_REF_DECL (orig)) && !(DECL_SECTION_NAME(decl))
- && !decl->common.typed.base.readonly_flag
-- && !decl->decl_with_vis.in_text_section && !section)
-+ && !decl->decl_with_vis.in_text_section)
- {
-
- /* SBF: unfortunately using the wrapped symbol without MEM does not work.
-
-From 5eb6023e66b9bdf3125e5381d11ac9992835f943 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Sat, 23 Dec 2017 11:54:08 +0100
-Subject: [PATCH 292/303] fix inlined functions - removed extern
-
----
- gcc/config/m68k/math-68881.h | 62 ++++++++++++++++++++++----------------------
- 1 file changed, 31 insertions(+), 31 deletions(-)
-
-diff --git a/gcc/config/m68k/math-68881.h b/gcc/config/m68k/math-68881.h
-index 6d9f8b2d4a1f..20a5037cc525 100644
---- gcc/config/m68k/math-68881.h
-+++ gcc/config/m68k/math-68881.h
-@@ -37,7 +37,7 @@
- September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif. */
-
- /* Changed by Ian Lance Taylor:
-- September 1994, use extern inline instead of static inline. */
-+ September 1994, use inline instead of static inline. */
-
- #ifndef __math_68881
- #define __math_68881
-@@ -64,7 +64,7 @@
- })
- #endif
-
--__inline extern double
-+__inline double
- sin (double x)
- {
- double value;
-@@ -75,7 +75,7 @@ sin (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- cos (double x)
- {
- double value;
-@@ -86,7 +86,7 @@ cos (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- tan (double x)
- {
- double value;
-@@ -97,7 +97,7 @@ tan (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- asin (double x)
- {
- double value;
-@@ -108,7 +108,7 @@ asin (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- acos (double x)
- {
- double value;
-@@ -119,7 +119,7 @@ acos (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atan (double x)
- {
- double value;
-@@ -130,7 +130,7 @@ atan (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atan2 (double y, double x)
- {
- double pi, pi_over_2;
-@@ -187,7 +187,7 @@ atan2 (double y, double x)
- }
- }
-
--__inline extern double
-+__inline double
- sinh (double x)
- {
- double value;
-@@ -198,7 +198,7 @@ sinh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- cosh (double x)
- {
- double value;
-@@ -209,7 +209,7 @@ cosh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- tanh (double x)
- {
- double value;
-@@ -220,7 +220,7 @@ tanh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atanh (double x)
- {
- double value;
-@@ -231,7 +231,7 @@ atanh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- exp (double x)
- {
- double value;
-@@ -242,7 +242,7 @@ exp (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- expm1 (double x)
- {
- double value;
-@@ -253,7 +253,7 @@ expm1 (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log (double x)
- {
- double value;
-@@ -264,7 +264,7 @@ log (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log1p (double x)
- {
- double value;
-@@ -275,7 +275,7 @@ log1p (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log10 (double x)
- {
- double value;
-@@ -286,7 +286,7 @@ log10 (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- sqrt (double x)
- {
- double value;
-@@ -297,13 +297,13 @@ sqrt (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- hypot (double x, double y)
- {
- return sqrt (x*x + y*y);
- }
-
--__inline extern double
-+__inline double
- pow (double x, double y)
- {
- if (x > 0)
-@@ -352,7 +352,7 @@ pow (double x, double y)
- }
- }
-
--__inline extern double
-+__inline double
- fabs (double x)
- {
- double value;
-@@ -363,7 +363,7 @@ fabs (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- ceil (double x)
- {
- int rounding_mode, round_up;
-@@ -385,7 +385,7 @@ ceil (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- floor (double x)
- {
- int rounding_mode, round_down;
-@@ -408,7 +408,7 @@ floor (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- rint (double x)
- {
- int rounding_mode, round_nearest;
-@@ -430,7 +430,7 @@ rint (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- fmod (double x, double y)
- {
- double value;
-@@ -442,7 +442,7 @@ fmod (double x, double y)
- return value;
- }
-
--__inline extern double
-+__inline double
- drem (double x, double y)
- {
- double value;
-@@ -454,7 +454,7 @@ drem (double x, double y)
- return value;
- }
-
--__inline extern double
-+__inline double
- scalb (double x, int n)
- {
- double value;
-@@ -466,7 +466,7 @@ scalb (double x, int n)
- return value;
- }
-
--__inline extern double
-+__inline double
- logb (double x)
- {
- double exponent;
-@@ -477,7 +477,7 @@ logb (double x)
- return exponent;
- }
-
--__inline extern double
-+__inline double
- ldexp (double x, int n)
- {
- double value;
-@@ -489,7 +489,7 @@ ldexp (double x, int n)
- return value;
- }
-
--__inline extern double
-+__inline double
- frexp (double x, int *exp)
- {
- double float_exponent;
-@@ -514,7 +514,7 @@ frexp (double x, int *exp)
- return mantissa;
- }
-
--__inline extern double
-+__inline double
- modf (double x, double *ip)
- {
- double temp;
-
-From 443179daa5f06a569a4de7e62c431d787c066f86 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Sat, 23 Dec 2017 13:18:20 +0100
-Subject: [PATCH 293/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 2d76043c1dd3..e70e15403ebc 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171221-195003
-+20171223-131819
-
-From b5b76e646e60f561e56608ad1839013fcc04d3cc Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 29 Dec 2017 10:20:42 +0100
-Subject: [PATCH 294/303] set -Os as default
-
----
- gcc/config.gcc | 1 +
- libgcc/config.host | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/gcc/config.gcc b/gcc/config.gcc
-index 0beee32c863c..59df5867053d 100644
---- gcc/config.gcc
-+++ gcc/config.gcc
-@@ -1955,6 +1955,7 @@ m68k*-*-amigaos*)
- extra_objs=amigaos.o
- extra_options="${extra_options} m68k/amigaos.opt"
- gnu_ld=yes
-+ CFLAGS="-Os"
- ;;
- m68k*-*-netbsdelf*)
- default_m68k_cpu=68020
-diff --git a/libgcc/config.host b/libgcc/config.host
-index c36e829a5025..0a88fa78c170 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -818,6 +818,7 @@ m32rle-*-linux*)
- ;;
- m68k-*-amiga*)
- tmake_file="$tmake_file m68k/t-glue m68k/t-floatlib soft-fp"
-+ CFLAGS="-Os"
- # tmake_file="$tmake_file m68k/t-glue soft-fp"
- ;;
- m68k-*-elf* | fido-*-elf)
-
-From 734f944e12181b7fd69e0447f68f1be7fcd13822 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 29 Dec 2017 10:21:49 +0100
-Subject: [PATCH 295/303] print insn before aborting
-
----
- gcc/emit-rtl.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
-index 0fcd9d95e5b4..b2a18e7e4188 100644
---- gcc/emit-rtl.c
-+++ gcc/emit-rtl.c
-@@ -2123,7 +2123,11 @@ change_address_1 (rtx memref, machine_mode mode, rtx addr, int validate,
- if (validate && !lra_in_progress)
- {
- if (reload_in_progress || reload_completed)
-- gcc_assert (memory_address_addr_space_p (mode, addr, as));
-+ {
-+ bool r = memory_address_addr_space_p (mode, addr, as);
-+ if (!r) debug_rtx(addr);
-+ gcc_assert (r);
-+ }
- else
- addr = memory_address_addr_space (mode, addr, as);
- }
-
-From 765a8c42eee2c949fc5d31b3e4693c8237bdb48b Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 29 Dec 2017 10:22:34 +0100
-Subject: [PATCH 296/303] fix a check with -fbaserel(32)
-
----
- gcc/config/m68k/m68k.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 29e2e45df844..4533427db7a7 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -1982,10 +1982,12 @@ m68k_legitimate_constant_address_p (rtx x, unsigned int reach, bool strict_p)
- if (!CONSTANT_ADDRESS_P (x))
- return false;
-
-- if (flag_pic
-+ if (flag_pic && flag_pic < 3
- && !(strict_p && TARGET_PCREL)
- && symbolic_operand (x, VOIDmode))
-- return false;
-+ {
-+ return false;
-+ }
-
- if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P && reach > 1)
- {
-
-From 44cf4734135f00e7949a431a308e5da436735300 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Fri, 29 Dec 2017 10:23:00 +0100
-Subject: [PATCH 297/303] enable multilib
-
----
- gcc/config/m68k/t-amigaos | 14 ++++++--------
- 1 file changed, 6 insertions(+), 8 deletions(-)
-
-diff --git a/gcc/config/m68k/t-amigaos b/gcc/config/m68k/t-amigaos
-index 112d5daa06fb..bf9c5279d04f 100755
---- gcc/config/m68k/t-amigaos
-+++ gcc/config/m68k/t-amigaos
-@@ -10,14 +10,6 @@ amigaos.o: $(srcdir)/config/m68k/amigaos.c $(CONFIG_H)
-
- #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
-
-@@ -28,3 +20,9 @@ amigacollect2.o: amigacollect2.c
- $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- -DA2IXDIR_PREFIX=\"$(prefix)/share/a2ixlibrary\" $< $(OUTPUT_OPTION)
- ### end-GG-local
-+
-+# Support for building multiple version of libgcc, libquadmath, libobjc and libstdc++-v3
-+MULTILIB_OPTIONS = m68020 fbaserel/fbaserel32
-+MULTILIB_DIRNAMES = libm020 libb libb32
-+MULTILIB_EXTRA_OPTS = noixemul
-+MULTILIB_EXCEPTIONS = fbaserel32
-\ No newline at end of file
-
-From e7906b06f6cba077f666b43dfa822c4117078a9a Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Fri, 29 Dec 2017 10:52:57 +0100
-Subject: [PATCH 298/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index e70e15403ebc..1ba74cfc6d61 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171223-131819
-+20171229-105257
-
-From 20fa3b9980630cf21b2a19f6f26e276840e0c7d5 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Wed, 10 Jan 2018 20:37:20 +0100
-Subject: [PATCH 299/303] refs #7: invalidate registers holding a memory
- referenc if a value is written to that memory reference
-
----
- gcc/bbb-opts.c | 34 +++++++++++++++++++++++++++++++---
- 1 file changed, 31 insertions(+), 3 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 432c9bb4bbd3..ae824bbfbb1a 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -238,13 +238,38 @@ class track_var
- if (o)
- assign (o);
- else
-- for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
- value[i] = 0;
- mask[i] = 0;
- }
+ #define YES (BOOL)1
+ #define NO (BOOL)0
+diff --git a/libstdc++-v3/config/os/newlib/ctype_configure_char.cc b/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
+index 903de5625d77..ed0c757d42f8 100644
+--- libstdc++-v3/config/os/newlib/ctype_configure_char.cc
++++ libstdc++-v3/config/os/newlib/ctype_configure_char.cc
+@@ -65,6 +65,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+ _M_narrow_ok = 0;
}
-+ void
-+ invalidate_mem(rtx dst) {
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (extend(&z, &m, GET_MODE(dst), dst))
-+ {
-+// unsigned hit = 0;
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (rtx_equal_p(z, value[i]))
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+// hit |= 1<<i;
-+ }
-+ }
-+// if (hit)
-+// {
-+// fprintf(stderr, "%08x", hit);
-+// debug_rtx(z);
-+// }
-+ }
++#ifdef __AMIGA__
++ ctype<char>::~ctype()
++ {
++ _S_destroy_c_locale(_M_c_locale_ctype);
++ if (_M_del)
++ delete[] this->table();
+ }
++#endif
+
-+
- rtx
- get (unsigned regno)
+ char
+ ctype<char>::do_toupper(char __c) const
{
-@@ -347,7 +372,7 @@ class track_var
- if (!rtx_equal_p (value[i], o->value[i]))
- {
- value[i] = o->value[i] = 0;
-- mask[i] = mask[i] = 0;
-+ mask[i] = 0;
- }
- }
- }
-@@ -3940,7 +3965,10 @@ track_regs ()
- continue;
+diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
+index 9bf152a01573..f162705f2625 100755
+--- libstdc++-v3/configure
++++ libstdc++-v3/configure
+@@ -8636,6 +8636,8 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
++ enable_shared=no
++ CXXFLAGS="$CXXFLAGS -noixemul"
+ ;;
+ esac
+ ;;
+@@ -28883,6 +28885,10 @@ else
- if (dregno < 0)
-- continue;
-+ {
-+ track->invalidate_mem(SET_DEST(set));
-+ continue;
-+ }
+ # Base decisions on target environment.
+ case "${host}" in
++ m68k-*-*)
++ # Nothing to do here.
++ ;;
++
+ arm*-*-symbianelf*)
+ # This is a freestanding configuration; there is nothing to do here.
+ ;;
+diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
+index 304a7f5aff61..fde4a72bd31b 100644
+--- libstdc++-v3/configure.host
++++ libstdc++-v3/configure.host
+@@ -226,6 +226,11 @@ case "${host_os}" in
+ os_include_dir="os/generic"
+ atomicity_dir="cpu/generic"
+ ;;
++ amiga*)
++ os_include_dir="os/newlib"
++ CFLAGS="-Os -noixemul"
++ CPPFLAGS="-Os -noixemul"
++ ;;
+ bsd*)
+ # Plain BSD attempts to share FreeBSD files.
+ os_include_dir="os/bsd/freebsd"
+diff --git a/libstdc++-v3/include/tr1/cstdint b/libstdc++-v3/include/tr1/cstdint
+index 7304d9008413..7d6ab77ce17a 100644
+--- libstdc++-v3/include/tr1/cstdint
++++ libstdc++-v3/include/tr1/cstdint
+@@ -30,7 +30,9 @@
+ #define _GLIBCXX_TR1_CSTDINT 1
- // operation, autoinf or more than one register used: can't cache
- if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) & ii.get_myuse ()))
-
-From 57be9251f4cb7adfd7850d21d7bd77d13474be32 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 11 Jan 2018 20:08:18 +0100
-Subject: [PATCH 300/303] opt_elim_dead_assign checks now if some register
- contains a value already and uses that reg
-
----
- gcc/bbb-opts.c | 41 +++++++++++++++++++++++++++++++----------
- 1 file changed, 31 insertions(+), 10 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index ae824bbfbb1a..3235c84deb4b 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -223,10 +223,11 @@ class track_var
- *z = gen_rtx_MEM (GET_MODE(x), m);
- return true;
- }
-+ default:
-+ return false;
- }
-- return false;
-+ break;
- }
+ #pragma GCC system_header
-
- default:
- return false;
- }
-@@ -245,27 +246,36 @@ class track_var
- }
- }
-
-+ int find_alias(rtx src)
-+ {
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (extend(&z, &m, GET_MODE(src), src))
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ // do not alias small int value from -128 ... 127
-+ if (rtx_equal_p(z, value[i]) && (GET_CODE(z) != CONST_INT || INTVAL(z) > 127 || INTVAL(z) < -128))
-+ return i;
-+ }
-+ }
-+ return -1;
-+ }
- void
-- invalidate_mem(rtx dst) {
-+ invalidate_mem(rtx dst)
-+ {
- rtx z = 0;
- unsigned m = 0;
- if (extend(&z, &m, GET_MODE(dst), dst))
- {
--// unsigned hit = 0;
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
- if (rtx_equal_p(z, value[i]))
- {
- value[i] = 0;
- mask[i] = 0;
--// hit |= 1<<i;
- }
- }
--// if (hit)
--// {
--// fprintf(stderr, "%08x", hit);
--// debug_rtx(z);
--// }
- }
- }
-
-@@ -4038,6 +4048,17 @@ opt_elim_dead_assign (int blocked_regno)
- continue;
- }
++#ifdef AMIGA
++#include <stdint.h>
++#endif
+ #include <bits/c++config.h>
-+ // is there a register holding that value?
-+ if (!ii.get_src_reg ())
-+ {
-+ int aliasRegno = track->find_alias(src);
-+ if (aliasRegno >= 0 && aliasRegno != ii.get_dst_regno())
-+ {
-+ log ("(e) %d: replace load with %s\n", index, reg_names[aliasRegno]);
-+ validate_change (ii.get_insn(), &SET_SRC(set), gen_rtx_REG(ii.get_mode(), aliasRegno), 0);
-+ ++change_count;
-+ }
-+ }
- }
- }
- return change_count;
-
-From 03065de1585bae453567dbf1c2352794fac793d1 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 11 Jan 2018 20:09:01 +0100
-Subject: [PATCH 301/303] reg rename may use the starting used register if it's
- dead there (Jim)
-
----
- gcc/bbb-opts.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 3235c84deb4b..2be2afe83c77 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -2332,6 +2332,10 @@ opt_reg_rename (void)
- /* get the mask for free registers. */
- unsigned mask = ii.get_free_mask ();
+ // For 8.22.1/1 (see C99, Notes 219, 220, 222)
+diff --git a/libstdc++-v3/src/c++11/ctype.cc b/libstdc++-v3/src/c++11/ctype.cc
+index fa370681dad5..f80e83034255 100644
+--- libstdc++-v3/src/c++11/ctype.cc
++++ libstdc++-v3/src/c++11/ctype.cc
+@@ -51,12 +51,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
-+ /* the mask contains the current src register. Add this register to the mask if it's dead here. */
-+ if (ii.get_src_reg() && is_reg_dead(ii.get_src_regno(), index))
-+ mask |= ii.get_use();
-+
- /* do not use a4 if compiling baserel */
- if (flag_pic >= 3)
- mask &= ~(1 << PIC_REG);
-
-From 14767273a413e13794aeec098ee0c54acce1b9d4 Mon Sep 17 00:00:00 2001
-From: bebbo <bebbo@bejy.net>
-Date: Thu, 11 Jan 2018 21:36:13 +0100
-Subject: [PATCH 302/303] change register order - prefer ax over dx to avoid
- address calculation in dx regs, improve opt_elim_dead_assign() to eliminate
- self assignments
-
----
- gcc/bbb-opts.c | 50 ++++++++++++++++++++++++++++----------------------
- gcc/config/m68k/m68k.h | 16 ++++++++++++++--
- 2 files changed, 42 insertions(+), 24 deletions(-)
-
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-index 2be2afe83c77..9e989e9b1ec0 100755
---- gcc/bbb-opts.c
-+++ gcc/bbb-opts.c
-@@ -246,31 +246,32 @@ class track_var
- }
- }
+ const size_t ctype<char>::table_size;
-- int find_alias(rtx src)
-+ int
-+ find_alias (rtx src)
- {
- rtx z = 0;
- unsigned m = 0;
-- if (extend(&z, &m, GET_MODE(src), src))
-+ if (extend (&z, &m, GET_MODE(src), src))
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
- // do not alias small int value from -128 ... 127
-- if (rtx_equal_p(z, value[i]) && (GET_CODE(z) != CONST_INT || INTVAL(z) > 127 || INTVAL(z) < -128))
-+ if (rtx_equal_p (z, value[i]) && (GET_CODE(z) != CONST_INT || INTVAL(z) > 127 || INTVAL(z) < -128))
- return i;
- }
- }
- return -1;
- }
- void
-- invalidate_mem(rtx dst)
-+ invalidate_mem (rtx dst)
- {
- rtx z = 0;
- unsigned m = 0;
-- if (extend(&z, &m, GET_MODE(dst), dst))
-+ if (extend (&z, &m, GET_MODE(dst), dst))
- {
- for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
- {
-- if (rtx_equal_p(z, value[i]))
-+ if (rtx_equal_p (z, value[i]))
- {
- value[i] = 0;
- mask[i] = 0;
-@@ -279,7 +280,6 @@ class track_var
- }
++#ifndef __AMIGA__
++/* moved to ctype_configure_char */
+ ctype<char>::~ctype()
+ {
+ _S_destroy_c_locale(_M_c_locale_ctype);
+ if (_M_del)
+ delete[] this->table();
}
-
--
- rtx
- get (unsigned regno)
- {
-@@ -1517,7 +1517,7 @@ find_reg_by_no (rtx x, unsigned oldregno)
- for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
- {
- rtx z = XVECEXP(x, i, j);
-- rtx r = find_reg_by_no(z, oldregno);
-+ rtx r = find_reg_by_no (z, oldregno);
- if (r)
- return r;
- }
-@@ -2333,8 +2333,8 @@ opt_reg_rename (void)
- unsigned mask = ii.get_free_mask ();
-
- /* the mask contains the current src register. Add this register to the mask if it's dead here. */
-- if (ii.get_src_reg() && is_reg_dead(ii.get_src_regno(), index))
-- mask |= ii.get_use();
-+ if (ii.get_src_reg () && is_reg_dead (ii.get_src_regno (), index))
-+ mask |= ii.get_use ();
-
- /* do not use a4 if compiling baserel */
- if (flag_pic >= 3)
-@@ -2497,11 +2497,11 @@ opt_reg_rename (void)
- rtx_insn * insn = rr.get_insn ();
-
- /* get rename locations. */
-- rtx from = find_reg_by_no(PATTERN (insn), oldregno);
-+ rtx from = find_reg_by_no (PATTERN (insn), oldregno);
- if (from)
- {
-- rtx to = gen_raw_REG(GET_MODE(from), newregno);
-- validate_replace_rtx_group(from, to, insn);
-+ rtx to = gen_raw_REG (GET_MODE(from), newregno);
-+ validate_replace_rtx_group (from, to, insn);
-
- positions.push_back (*i);
- }
-@@ -3945,11 +3945,17 @@ track_regs ()
- if (ii.is_compare ())
- continue;
-
-- int dregno = ii.get_dst_regno ();
-- track->clear (ii.get_mode (), dregno, index);
--
- unsigned def = ii.get_def () & 0xffffff;
-- track->clear_for_mask (def, index);
-+ if (def)
-+ {
-+ // more than one register set? or mask from clobber?
-+ if (((def - 1) & def) || !ii.get_dst_reg ())
-+ track->clear_for_mask (def, index);
-+ }
-+ // do not clear if self assigned
-+ int dregno = ii.get_dst_regno ();
-+ if (dregno != ii.get_src_regno ())
-+ track->clear (ii.get_mode (), dregno, index);
-
- if (ii.is_call ())
- {
-@@ -3980,7 +3986,7 @@ track_regs ()
-
- if (dregno < 0)
- {
-- track->invalidate_mem(SET_DEST(set));
-+ track->invalidate_mem (SET_DEST(set));
- continue;
- }
-
-@@ -4031,7 +4037,7 @@ opt_elim_dead_assign (int blocked_regno)
-
- // check for redundant load
- if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno () != blocked_regno
-- && !ii.is_myuse (ii.get_dst_regno ()))
-+ && (!ii.is_myuse (ii.get_dst_regno ()) || ii.get_dst_regno () == ii.get_src_regno ()))
- {
- track_var * track = ii.get_track_var ();
-
-@@ -4055,11 +4061,11 @@ opt_elim_dead_assign (int blocked_regno)
- // is there a register holding that value?
- if (!ii.get_src_reg ())
- {
-- int aliasRegno = track->find_alias(src);
-- if (aliasRegno >= 0 && aliasRegno != ii.get_dst_regno())
-+ int aliasRegno = track->find_alias (src);
-+ if (aliasRegno >= 0 && aliasRegno != ii.get_dst_regno ())
- {
- log ("(e) %d: replace load with %s\n", index, reg_names[aliasRegno]);
-- validate_change (ii.get_insn(), &SET_SRC(set), gen_rtx_REG(ii.get_mode(), aliasRegno), 0);
-+ validate_change (ii.get_insn (), &SET_SRC(set), gen_rtx_REG (ii.get_mode (), aliasRegno), 0);
- ++change_count;
- }
- }
-diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
-index 6cdc635d4df3..278b048ae237 100644
---- gcc/config/m68k/m68k.h
-+++ gcc/config/m68k/m68k.h
-@@ -378,13 +378,25 @@ along with GCC; see the file COPYING3. If not see
- /* Arg pointer. */ \
- 1 }
-
-+#if 0
- #define REG_ALLOC_ORDER \
- { /* d0/d1/a0/a1 */ \
- 0, 1, 8, 9, \
- /* d2-d7 */ \
-- 2, 3, 4, 5, 6, 7, \
-+ 2, 10, 3, 11, 4, 5, 6, 7, \
- /* a2-a7/arg */ \
-- 10, 11, 12, 13, 14, 15, 24, \
-+ 12, 13, 14, 15, 24, \
-+ /* fp0-fp7 */ \
-+ 16, 17, 18, 19, 20, 21, 22, 23\
-+}
+#endif
-+#define REG_ALLOC_ORDER \
-+{ /* d0/d1/a0/a1 */ \
-+ 0, 8, 9, 1, \
-+ /* a2-a7 */ \
-+ 10, 11, 12, 13, 14, 15, \
-+ /* d2-d7/arg */ \
-+ 2, 3, 4, 5, 6, 7, 24, \
- /* fp0-fp7 */ \
- 16, 17, 18, 19, 20, 21, 22, 23\
- }
-
-From 359713c99b0cbf7744ad3158929c53fb304e3ce4 Mon Sep 17 00:00:00 2001
-From: fautomat <automat@franke.ms>
-Date: Thu, 11 Jan 2018 22:28:38 +0100
-Subject: [PATCH 303/303] bump version DATESTAMP
-
----
- gcc/DATESTAMP | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
-index 1ba74cfc6d61..97461d26bd27 100644
---- gcc/DATESTAMP
-+++ gcc/DATESTAMP
-@@ -1 +1 @@
--20171229-105257
-+20180111-222838
+
+ // Fill in the narrowing cache and flag whether all values are
+ // valid or not. _M_narrow_ok is set to 2 if memcpy can't