From af2eff8eba15f5fb1d54eb4cf7b8a4de24eb922a Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sat, 13 Jan 2018 00:07:35 +0000 Subject: Update to gcc 6.4 --- m68k-unknown-amigaos/Makefile | 6 +- .../recipes/files/gcc/gcc/amigacollect2.c | 349 - .../files/gcc/gcc/config/m68k/amigaos-protos.h | 45 - .../recipes/files/gcc/gcc/config/m68k/amigaos.c | 461 - .../recipes/files/gcc/gcc/config/m68k/amigaos.h | 553 - .../files/gcc/gcc/config/m68k/host-amigaos.c | 42 - .../recipes/files/gcc/gcc/config/m68k/t-amigaos | 30 - .../recipes/files/gcc/gcc/config/m68k/x-amigaos | 104 - .../recipes/files/gcc/gcc/config/m68k/xm-amigaos.h | 64 - .../recipes/files/gcc/gcc/doc/gcc-amigaos.texi | 1116 - m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p | 51494 ++++--------------- 11 files changed, 9814 insertions(+), 44450 deletions(-) delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/amigacollect2.c delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos-protos.h delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.c delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/amigaos.h delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/host-amigaos.c delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/t-amigaos delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/x-amigaos delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/config/m68k/xm-amigaos.h delete mode 100644 m68k-unknown-amigaos/recipes/files/gcc/gcc/doc/gcc-amigaos.texi (limited to 'm68k-unknown-amigaos') 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; ilast_arg_len; i++) - if (cum->regs_already_used & (1 << cum->last_arg_reg+i)) - { - error("two parameters allocated for one register"); - break; - } - return gen_rtx_REG (mode, cum->last_arg_reg); - } - else - return m68k_function_arg(cum, mode, type); -} - -/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible, - one if they are compatible, and two if they are nearly compatible - (which causes a warning to be generated). */ - -int -amigaos_comp_type_attributes (tree type1, tree type2) -{ - /* Functions or methods are incompatible if they specify mutually exclusive - ways of passing arguments. */ - if (TREE_CODE(type1)==FUNCTION_TYPE || TREE_CODE(type1)==METHOD_TYPE) - { - tree arg1, arg2; - arg1=TYPE_ARG_TYPES(type1); - arg2=TYPE_ARG_TYPES(type2); - for (; arg1 && arg2; arg1=TREE_CHAIN(arg1), arg2=TREE_CHAIN(arg2)) - if (TREE_VALUE(arg1) && TREE_VALUE(arg2)) - { - tree asm1, asm2; - asm1=lookup_attribute("asm", 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 -#endif - -/* AmigaOS specific headers, such as from the Native Developer Update kits, - go in SYSTEM_INCLUDE_DIR. STANDARD_INCLUDE_DIR is the equivalent of - Unix "/usr/include". All other include paths are set in Makefile. */ - -#define SYSTEM_INCLUDE_DIR "/gg/os-include" -#define STANDARD_INCLUDE_DIR "/gg/include" - -#define STANDARD_EXEC_PREFIX_1 "/gg/libexec/gcc/" -#define STANDARD_EXEC_PREFIX_2 "/gg/lib/gcc/" -#define STANDARD_STARTFILE_PREFIX_1 "/gg/lib/" -#define STANDARD_STARTFILE_PREFIX_2 "/gg/lib/" - -/* The AmigaOS stores file names with regard to upper/lower case, but actions - on existing files are case independent on the standard filesystems. - - A good example of where this causes problems is the conflict between the C - include file and the C++ include file , where the C++ - include file dir is searched first and thus causes includes of - to include instead. - - In order to solve this problem we define the macro OPEN_CASE_SENSITIVE as - the name of the function that takes the same args as open() and does case - dependent opens. */ - -#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE)) - -/* On the AmigaOS, there are two pathname separators, '/' (DIR_SEPARATOR) - and ':' (VOL_SEPARATOR). DIR_SEPARATOR defaults to the correct - character, so we don't have to explicitly set it. */ - -#define DIR_SEPARATOR '/' -#define VOL_SEPARATOR ':' -#define DIR_SEPARATOR_2 VOL_SEPARATOR - -/* Zap PREFIX_INCLUDE_DIR, since with the AmigaOS port it is the same as - STANDARD_INCLUDE_DIR. */ - -#undef PREFIX_INCLUDE_DIR diff --git a/m68k-unknown-amigaos/recipes/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 or, even better, -to the mailing list. - -The author would like to thank Kriton Kyrimis and -Lars Hecking 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[=] -@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:: is not the same as -* 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 is not the same as - -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,21596 +1,1499 @@ -From 64dc72223bfc308f487ea8c70c6f961075cd4f24 Mon Sep 17 00:00:00 2001 -From: bebbo -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/gcc/Makefile.in b/gcc/Makefile.in -index 513f9c57013f..c1986279752f 100644 ---- gcc/Makefile.in -+++ gcc/Makefile.in -@@ -1985,7 +1985,7 @@ gcc-nm.c: gcc-ar.c - cp $^ $@ - - COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o \ -- collect-utils.o file-find.o hash-table.o -+ collect-utils.o file-find.o hash-table.o $(EXTRA_COLLECT2_OBJS) - COLLECT2_LIBS = @COLLECT2_LIBS@ - collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) - # Don't try modifying collect2 (aka ld) in place--it might be linking this. -diff --git a/gcc/amigacollect2.c b/gcc/amigacollect2.c +diff --git a/.cproject b/.cproject new file mode 100755 -index 000000000000..941ea0248fbe +index 000000000000..6db4cbe2447e --- /dev/null -+++ gcc/amigacollect2.c -@@ -0,0 +1,348 @@ -+/* 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_error(location_t, const char *, ...); -+void fork_execute(const char *, char **, bool); -+ -+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_error (input_location, "%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=(char*) -+ 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=(char*)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_error (input_location, "%s", XLIBS_C_NAME); -+ x = fopen(SHARED_X_NAME, "w"); -+ if (x == NULL) -+ fatal_error (input_location, "%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, false); -+ -+ /* 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_error (input_location, "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, 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 -new file mode 100755 -index 000000000000..90bc3218bab7 ---- /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). -+ -+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" -+ -+ -+#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) -+{ -+ 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. */ -+ -+ cum->last_arg_reg = -1; -+ cum->regs_already_used = 0; -+ -+ if (fntype) -+ { -+ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(fntype))) -+ cum->num_of_regs = 0; -+ else -+ { -+ tree ratree = lookup_attribute ("regparm", TYPE_ATTRIBUTES(fntype)); -+ cum->num_of_regs = amigaos_regparm ? -+ 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; -+} -+ -+/* 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 */ -+ else -+ regbegin = 0; /* Dx */ -+ altregbegin = 8 - regbegin; -+ len = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; -+ } -+ -+ if (regbegin != -1) -+ { -+ int reg; -+ long mask; -+ -+ look_for_reg: mask = 1 << regbegin; -+ for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1) -+ if (!(cum->regs_already_used & mask)) -+ { -+ int end; -+ for (end = reg; end < cum->num_of_regs && end < reg + len; -+ end++, mask <<= 1) -+ if (cum->regs_already_used & mask) -+ break; -+ if (end == reg + len) -+ { -+ cum->last_arg_reg = reg + regbegin; -+ cum->last_arg_len = len; -+ break; -+ } -+ } -+ -+ if (reg == cum->num_of_regs && altregbegin != -1) -+ { -+ regbegin = altregbegin; -+ altregbegin = -1; -+ goto look_for_reg; -+ } -+ } -+ -+ if (cum->last_arg_reg != -1) -+ { -+ // printf("-> 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; -+ -+ // 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)) -+ { -+ 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); -+// 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 (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; -+ } -+ } -+ 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) -+{ -+// 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; -+} -+ -+ -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. -+ -+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 TARGET_AMIGAOS -+#define TARGET_AMIGAOS 1 -+#endif -+ -+#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 -+ -+/* 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) -+ -+#endif -+ -+/* Compile using the first 'm68k_regparm' data, address and float -+ registers for arguments passing. */ -+/*#define SUBTARGET_OPTIONS { "regparm=", &m68k_regparm_string, \ -+ N_("Use this register count to pass arguments"), 0},*/ -+ -+ -+/* Nonzero if we need to generate special stack-allocating insns. -+ On most systems they are not needed. -+ When they are needed, also define ALTERNATE_ALLOCATE_STACK (see m68k.md) -+ to perform the necessary actions. */ -+//#undef TARGET_ALTERNATE_ALLOCATE_STACK -+//#define TARGET_ALTERNATE_ALLOCATE_STACK 0 -+ -+ -+/* 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") } -+ -+#if 0 -+/* Various ABI issues. */ -+ -+/* This is (almost;-) BSD, so it wants DBX format. */ -+#undef DBX_DEBUGGING_INFO -+#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 -+ -+/* 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) -+ -+#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. */ -+ -+#undef FRAME_POINTER_REGNUM -+#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)]) -+ -+ -+/* The AmigaOS ABI does not define how structures should be returned, so, -+ contrary to 'm68k.h', we prefer a multithread-safe solution. */ -+ -+#undef PCC_STATIC_STRUCT_RETURN -+ -+/* Setup a default shell return value for those (gazillion..) programs that -+ (inspite of ANSI-C) declare main() to be void (or even VOID...) and thus -+ cause the shell to randomly caugh upon executing such programs (contrary -+ to Unix, AmigaOS scripts are terminated with an error if a program returns -+ with an error code above the `error' or even `failure' level -+ (which is configurable with the FAILAT command)). */ -+ -+//+2004-06-24 Ulrich Weigand -+//+ -+//+ * c-decl.c (finish_function): Do not check for DEFAULT_MAIN_RETURN. -+//+ * system.h (DEFAULT_MAIN_RETURN): Poison. -+//+ * doc/tm.texi (DEFAULT_MAIN_RETURN): Remove documentation. -+//+ -+ -+//poison VAR -+//#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node) -+ -+#undef WCHAR_TYPE -+#define WCHAR_TYPE "unsigned int" -+ -+/* XXX: section support */ -+#if 0 -+/* Support sections in chip memory, currently '.datachip' only. */ -+#undef TARGET_ASM_NAMED_SECTION -+#define TARGET_ASM_NAMED_SECTION amiga_named_section -+ -+/* We define TARGET_ASM_NAMED_SECTION, but we don't support arbitrary sections, -+ including '.gcc_except_table', so we emulate the standard behaviour. */ -+#undef TARGET_ASM_EXCEPTION_SECTION -+#define TARGET_ASM_EXCEPTION_SECTION amiga_exception_section -+ -+#undef TARGET_ASM_EH_FRAME_SECTION -+#define TARGET_ASM_EH_FRAME_SECTION amiga_eh_frame_section -+#endif -+ -+/* Use sjlj exceptions because dwarf work only on elf targets */ -+#undef DWARF2_UNWIND_INFO -+#define DWARF2_UNWIND_INFO 0 -+ -+ -+/* This is how to output an assembler line that says to advance the -+ location counter to a multiple of 2**LOG bytes. */ -+ -+#ifndef ALIGN_ASM_OP -+#define ALIGN_ASM_OP "\t.align\t" -+#endif -+ -+/* 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) -+ -+/* 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) -+ -+ -+/* 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) -+ -+#if 0 -+#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) -+#endif -+ -+/* begin-GG-local: dynamic libraries */ -+ -+extern int amigaos_do_collecting (void); -+extern void amigaos_gccopts_hook (const char *); -+extern void amigaos_libname_hook (const char* arg); -+extern void amigaos_collect2_cleanup (void); -+extern void amigaos_prelink_hook (const char **, int *); -+extern void amigaos_postlink_hook (const char *); -+ -+/* This macro is used to check if all collect2 facilities should be used. -+ We need a few special ones, like stripping after linking. */ -+ -+#define DO_COLLECTING (do_collecting || amigaos_do_collecting()) -+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) //new -+ -+/* This macro is called in collect2 for every GCC argument name. -+ ARG is a part of commandline (without '\0' at the end). */ -+ -+#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG) -+ -+/* This macro is called in collect2 for every ld's "-l" or "*.o" or "*.a" -+ argument. ARG is a complete argument, with '\0' at the end. */ -+ -+#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG) -+ -+/* This macro is called at collect2 exit, to clean everything up. */ -+ -+#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup -+ -+/* This macro is called just before the first linker invocation. -+ LD1_ARGV is "char** argv", which will be passed to "ld". STRIP is an -+ *address* of "strip_flag" variable. */ -+ -+#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \ -+amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP)) -+ -+/* This macro is called just after the first linker invocation, in place of -+ "nm" and "ldd". OUTPUT_FILE is the executable's filename. */ -+ -+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) -+/* end-GG-local */ -+ -+#endif -+ -+/* begin-GG-local: explicit register specification for parameters */ -+ -+/* Note: this is an extension of m68k_args */ -+ -+ -+/* A C type for declaring a variable that is used as the first -+ argument of `FUNCTION_ARG' and other related values. */ -+/* Max. number of data, address and float registers to be used for passing -+ integer, pointer and float arguments when TARGET_REGPARM. -+ It's 4, so d0-d3, a0-a3 and fp0-fp3 can be used. */ -+#undef 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=' 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: -+ 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. -+*/ -+ -+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*); -+ -+/* 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 TARGET_FUNCTION_ARG_ADVANCE -+#define TARGET_FUNCTION_ARG_ADVANCE amigaos_function_arg_advance -+ -+/* A C expression that controls whether a function argument is passed -+ in a register, and which register. */ -+ -+#undef TARGET_FUNCTION_ARG -+#define TARGET_FUNCTION_ARG amigaos_function_arg -+ -+#undef TARGET_PACK_CUMULATIVE_ARGS -+#define TARGET_PACK_CUMULATIVE_ARGS(CUM) \ -+ (amigaos_pack_cumulative_args(&(CUM))) -+ -+#undef TARGET_COMP_TYPE_ATTRIBUTES -+#define TARGET_COMP_TYPE_ATTRIBUTES amigaos_comp_type_attributes -+ -+ -+/* end-GG-local */ -+ -+#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) -+ -+/* { 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 }, -+ -+#define GOT_SYMBOL_NAME "" -+ -+#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) -+{ -+ 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 */ -+ -+/* Target definitions for GNU compiler for mc680x0 running AmigaOs -+ Copyright (C) 1991-2016 Free Software Foundation, Inc. -+ -+ Written by Ron Guilmette (rfg@netcom.com) and Fred Fish (fnf@cygnus.com). -+ -+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 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. -+ -+You should have received a copy of the GNU General Public License -+along with GCC; see the file COPYING3. If not see -+. */ -+ -+#ifndef TARGET_AMIGA -+#define TARGET_AMIGA 1 -+#endif -+ -+#ifndef SWBEG_ASM_OP -+#define SWBEG_ASM_OP "\t.swbeg\t" -+#endif -+ -+#undef PIC_REG -+#define PIC_REG 12 -+ -+#undef FRAME_POINTER_REGNUM -+#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)]) -+ -+ -+ -+/* 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. */ -+ -+/* 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 */ -+ -+#undef REGISTER_PREFIX -+#define REGISTER_PREFIX "" -+ -+/* The prefix for local (compiler generated) labels. -+ These labels will not appear in the symbol table. */ -+ -+#undef LOCAL_LABEL_PREFIX -+#define LOCAL_LABEL_PREFIX "." -+ -+/* The prefix to add to user-visible assembler symbols. */ -+ -+#undef USER_LABEL_PREFIX -+#define USER_LABEL_PREFIX "_" -+ -+/* config/m68k.md has an explicit reference to the program counter, -+ prefix this by the register prefix. */ -+ -+#define ASM_RETURN_CASE_JUMP \ -+ do { \ -+ return "jmp %%pc@(2,%0:w)"; \ -+ } while (0) -+ -+/* This is how to output an assembler line that says to advance the -+ location counter to a multiple of 2**LOG bytes. */ -+ -+#ifndef ALIGN_ASM_OP -+#define ALIGN_ASM_OP "\t.align\t" -+#endif -+ -+#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) -+ -+/* 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. */ -+ -+#undef M68K_STRUCT_VALUE_REGNUM -+#define M68K_STRUCT_VALUE_REGNUM A0_REG -+ -+/* The static chain regnum defaults to a0, but we use that for -+ structure return, so have to use a1 for the static chain. */ -+ -+#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" -+ -+#define ASM_COMMENT_START "|" -+ -+/* 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. */ -+ -+#undef DBX_REGISTER_NUMBER -+#define DBX_REGISTER_NUMBER(REGNO) (REGNO) -+ -+#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 -+ -+#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))) -+ -+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -+( fputs (".lcomm ", (FILE)), \ -+ assemble_name ((FILE), (NAME)), \ -+ fprintf ((FILE), ",%u\n", (int)(SIZE))) -+ -+/* 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 -+ -+/* 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 */ -+ -+#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" -+#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) -+#endif -+ -+ -+/* Specs, switches. */ -+ -+/* amiga/amigaos are the new "standard" defines for the Amiga. -+ MCH_AMIGA, AMIGA, __chip etc. are used in other compilers and are -+ provided for compatibility reasons. -+ When creating shared libraries, use different 'errno'. */ -+ -+ -+ -+#undef TARGET_OS_CPP_BUILTINS -+#define TARGET_OS_CPP_BUILTINS() \ -+ do \ -+ { \ -+ builtin_define ("__chip=__attribute__((__chip__))"); \ -+ builtin_define ("__saveds=__attribute__((__saveds__))"); \ -+ builtin_define ("__interrupt=__attribute__((__interrupt__))"); \ -+ builtin_define ("__stackext=__attribute__((__stackext__))"); \ -+ builtin_define ("__regargs_x=__attribute__((regparm))"); \ -+ builtin_define ("__stdargs_x=__attribute__((stkparm))"); \ -+ builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \ -+ builtin_define_std ("amiga"); \ -+ builtin_define_std ("amigaos"); \ -+ builtin_define_std ("AMIGA"); \ -+ builtin_define_std ("MCH_AMIGA"); \ -+ builtin_assert ("system=amigaos"); \ -+ } \ -+ while (0) -+ -+#if 0 -+if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \ -+ builtin_define ("errno=(*ixemul_errno)"); \ -+ -+#endif -+ -+/* Inform the program which CPU we compile for. */ -+ -+//#undef TARGET_CPU_CPP_BUILTINS -+/* -+ use --with-cpu=mc68040 etc.. instead on config. code was after #define TARGET_CPU_CPP_BUILTINS() -+ if (TARGET_68040_ONLY) \ -+ { \ -+ if (TARGET_68060) \ -+ builtin_define_std ("mc68060"); \ -+ else \ -+ builtin_define_std ("mc68040"); \ -+ } \ -+ else if (TARGET_68030 && !TARGET_68040) \ -+ builtin_define_std ("mc68030"); \ -+ else if (TARGET_68020) \ -+ builtin_define_std ("mc68020"); \ -+ builtin_define_std ("mc68000"); \ -+*/ -+/* -+#define TARGET_CPU_CPP_BUILTINS() \ -+ do \ -+ { \ -+ builtin_define_std ("mc68040"); \ -+ if (flag_pic > 2) \ -+ { \ -+ builtin_define ("__pic__"); \ -+ if (flag_pic > 3) \ -+ builtin_define ("__PIC__"); \ -+ } \ -+ builtin_assert ("cpu=m68k"); \ -+ builtin_assert ("machine=m68k"); \ -+ } \ -+ while (0) -+*/ -+/* Define __HAVE_68881__ in preprocessor according to the -m flags. -+ This will control the use of inline 68881 insns in certain macros. -+ Note: it should be set in TARGET_CPU_CPP_BUILTINS but TARGET_68881 -+ isn't the same -m68881 since its also true for -m680[46]0 ... -+ Differentiate between libnix and ixemul. */ -+ -+#define CPP_SPEC \ -+ "%{m68881:-D__HAVE_68881__} " \ -+ "%{!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. */ -+ -+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) -+/* end-GG-local */ -+ -+#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" -+ -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. -+ -+# 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) -+ -+# 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 -+ $(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 -+ -+# 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/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). -+ -+This file is part of GCC. -+ -+GCC is free software; you can redistribute it and/or modify -+it under the terms of the GNU General Public License as published by -+the Free Software Foundation; either version 2, or (at your option) -+any later version. -+ -+GCC is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+You should have received a copy of the GNU General Public License -+along with GCC; see the file COPYING. If not, write to -+the Free Software Foundation, 59 Temple Place - Suite 330, -+Boston, MA 02111-1307, USA. */ -+ -+#ifndef _FCNTL_H_ -+#include -+#endif -+ -+/* AmigaOS specific headers, such as from the Native Developer Update kits, -+ go in SYSTEM_INCLUDE_DIR. STANDARD_INCLUDE_DIR is the equivalent of -+ Unix "/usr/include". All other include paths are set in Makefile. */ -+ -+#define SYSTEM_INCLUDE_DIR "/gg/os-include" -+#define STANDARD_INCLUDE_DIR "/gg/include" -+ -+#define STANDARD_EXEC_PREFIX_1 "/gg/libexec/gcc/" -+#define STANDARD_EXEC_PREFIX_2 "/gg/lib/gcc/" -+#define STANDARD_STARTFILE_PREFIX_1 "/gg/lib/" -+#define STANDARD_STARTFILE_PREFIX_2 "/gg/lib/" -+ -+/* The AmigaOS stores file names with regard to upper/lower case, but actions -+ on existing files are case independent on the standard filesystems. -+ -+ A good example of where this causes problems is the conflict between the C -+ include file and the C++ include file , where the C++ -+ include file dir is searched first and thus causes includes of -+ to include instead. -+ -+ In order to solve this problem we define the macro OPEN_CASE_SENSITIVE as -+ the name of the function that takes the same args as open() and does case -+ dependent opens. */ -+ -+#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE)) -+ -+/* On the AmigaOS, there are two pathname separators, '/' (DIR_SEPARATOR) -+ and ':' (VOL_SEPARATOR). DIR_SEPARATOR defaults to the correct -+ character, so we don't have to explicitly set it. */ -+ -+#define DIR_SEPARATOR '/' -+#define VOL_SEPARATOR ':' -+#define DIR_SEPARATOR_2 VOL_SEPARATOR -+ -+/* Zap PREFIX_INCLUDE_DIR, since with the AmigaOS port it is the same as -+ STANDARD_INCLUDE_DIR. */ -+ -+#undef PREFIX_INCLUDE_DIR -diff --git a/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. -+ ;; -+ - arm*-*-symbianelf*) - # This is a freestanding configuration; there is nothing to do here. - ;; - -From 6951210c6e4901b5e963a19f5cae44bc0560a915 Mon Sep 17 00:00:00 2001 -From: bebbo -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 @@ -+ -+ -+ gcc-6 -+ -+ -+ -+ -+ -+ -+ -+ - -From c81713312a097d40d212a5ac5bce13b1aff7b226 Mon Sep 17 00:00:00 2001 -From: bebbo -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. */ -+ -+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); -+} -+ -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") } -- -+ -+ -+/* Support sections in chip memory, currently '.datachip' only. */ -+extern void -+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. */ - -@@ -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 -+ - - /* 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 -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 -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 -+ -+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 -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 -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 -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 -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; -+ - #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 -+ -+resident -+Target Common Report Var(flag_mybaserel,1) -+data is adressed relativ to a4, linked as resident -+ -+resident32 -+Target Common Report Var(flag_mybaserel,2) -+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 -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); -+ -+ if (!RTX_FLAG (addr, frame_related)) -+ { -+// 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 -+ - #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; -+ -+#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) -+ -+#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 -+ - /* 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)) -+ - /* 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) - */ -+ -+/* 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" -+ - /* 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 "" -+ -+#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}" -+ -+#define LIB_SPEC \ -+ "%{noixemul:%(lib_libnix)} " \ -+ "%{mcrt=nix*:%(lib_libnix)} " \ -+ "%{mcrt=ixemul:%(lib_ixemul)} " \ -+ "%{mcrt=clib2:%(lib_clib2)}" -+ -+#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)}" -+ -+/* 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. */ -+ -+#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}" -+ -+/* 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. */ -+ -+#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*} }}}}}} " \ -+ -+ - - /* 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 -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 -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 -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." -+ -+ 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) - - -From 5d9da9f9a2d9fec32fba2b7b9f2326d1f1c4f1f0 Mon Sep 17 00:00:00 2001 -From: bebbo -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; - } -+ -+ // 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/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) -+ { -+ 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; -+ } - 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 -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 -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 -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 -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 -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) -+ { -+ *p = 0; -+ p = strrchr(glp, '/'); -+ if (p) -+ { -+ p[1] = 0; -+ p = concat(glp, "m68k-amigaos/", 0); -+ } -+ } -+ } -+ 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 -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 -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 - #include - - // For 8.22.1/1 (see C99, Notes 219, 220, 222) - -From 8a098e5a7bb1c14c1afa7946dce4416596418e8a Mon Sep 17 00:00:00 2001 -From: bebbo -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 -+#endif - #include - - // For 8.22.1/1 (see C99, Notes 219, 220, 222) - -From a3e959953b7386e1576961fb4666f704b2edac7f Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 -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 -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 -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 -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 -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 -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 -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) -+ { -+ /* 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 - } - } - else - -From c72e9ebfc07a0b31d523b9d7428544427fe551b7 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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. */ -+ -+/** -+ * 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; -+} -+ -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); -+ -+ /* 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)) -+ { -+ print_operand_address(file, XEXP(addr, 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 (); - -@@ -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); -+ -+#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)) -+ -+ -+/* 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)) -+ -+// (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 -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]; -+} -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 -+ - @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]; -+ -+ /* 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); -+ -+ 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; - } - -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); -+} -+ - /* 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 -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 -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 -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 -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)) -+ 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 -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 -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) -+ { -+ 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 -@@ -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); -+ } -+ - /* 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 -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; -- } -+ } - } - } - } -@@ -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 -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 -+ -+ramiga-dev -+Target RejectNegative -+Use devinit.o as start file -+ - msmall-code - Target RejectNegative Var(flag_smallcode,1) - small code model - -From d62a4d349a55a59aa9d8b9a3f02827d66be960b4 Mon Sep 17 00:00:00 2001 -From: bebbo -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))) || -+ -+#undef TARGET_GCC_EXCEPT_TABLE -+#define TARGET_GCC_EXCEPT_TABLE ".data" -+ -+#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" -+ -+#ifndef TARGET_GCC_EXCEPT_TABLE -+#define TARGET_GCC_EXCEPT_TABLE ".gcc_except_table" -+#endif -+ -+#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 -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 -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" -+ -+#define EH_TABLES_CAN_BE_READ_ONLY 1 -+ -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 -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 -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 -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 -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 -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. -+ -+ 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 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. -+ -+ You should have received a copy of the GNU General Public License -+ along with GCC; see the file COPYING3. If not see -+ . */ -+ -+/** -+ * 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 -+ */ -+ -+#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 -+#include -+ -+extern void -+dump_insns (char const * name); -+ -+/* -+ * #1 propagate a->b->a moves out of a loop. -+ * -+ * consider a loop: -+ * -+ * .L1 -+ * ... -+ * move d0, a0 ; (1) -+ * ... -+ * move xy, (a0)+ -+ * ... -+ * move a0, d0 ; (2) -+ * ... -+ * jxx .L1 -+ * -+ * Then the statements (1) and (2) can be moved out of the loop: -+ * -+ * move d0, a0 ; (3) -+ * .L1 -+ * ... -+ * move *, (a0)+ ; a0 is modified somehow -+ * ... -+ * jxx .L1 -+ * move a0, d0 ; (4) -+ * -+ * if all criteria are met: -+ * -+ * a) no other jump to .L1 -> (LABEL_NUSES(insn) == 1) -+ * b) no other use of d0 inside the loop -+ * c) no other use of a0 before (1) -+ * d) no other use of a1 after (2) -+ * -+ * Optional: -+ * - omit (4) if d0 is dead -+ * -+ * this will e.g. convert -+ .L6: -+ move.l d0,a1 -+ move.b (a1)+,d1 -+ move.l a1,d0 -+ move.b d1,(a0)+ -+ cmp.b #0, d1 -+ jne .L6 -+ * to -+ move.l d0,a1 -+ .L6: -+ move.b (a1)+,d1 -+ move.b d1,(a0)+ -+ cmp.b #0, d1 -+ jne .L6 -+ * -+ */ -+static int -+propagate_moves () -+{ -+ rtx_insn *insn, *next; -+ rtx_insn * current_label = 0; -+ int change_count = 0; -+ std -+ ::vector reg_reg; -+ -+ for (insn = get_insns (); insn; insn = next) -+ { -+ next = NEXT_INSN (insn); -+ -+ if (DEBUG_INSN_P(insn)) -+ continue; -+ -+ if (LABEL_P(insn)) -+ { -+ if (LABEL_NUSES(insn) == 1) -+ { -+ current_label = insn; -+ reg_reg.clear (); -+ } -+ else -+ current_label = 0; -+ } -+ -+ if (current_label == 0) -+ continue; -+ -+ if (NONJUMP_INSN_P(insn)) -+ { -+ // check for set reg, reg -+ rtx set = single_set (insn); -+ if (set) -+ { -+ rtx src = SET_SRC(set); -+ rtx dst = SET_DEST(set); -+ if (REG_P(src) && REG_P(dst)) -+ reg_reg.push_back (insn); -+ } -+ continue; -+ } -+ -+ if (JUMP_P(insn)) -+ { -+ if (JUMP_LABEL (insn) == current_label && reg_reg.size () > 1) -+ { -+ /* Search for reg/reg pairs. */ -+ for (auto 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 ();) -+ { -+ rtx seti = single_set (*i); -+ rtx srci = SET_SRC(seti); -+ rtx dsti = SET_DEST(seti); -+ rtx setj = single_set (*j); -+ 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)) -+ { -+ 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; -+ } -+ } -+ if (inc) -+ ++j; -+ } -+ if (inc) -+ ++i; -+ } -+ } -+ current_label = 0; -+ } -+ } -+ -+ return change_count; -+} -+ -+/** -+ * Search for -+ * -+ * mov x,reg -+ * mov reg,x -+ * cmp #0, reg -+ * jxx -+ * -+ * patterns. -+ * -+ * Use a simple state machine to find the patterns. -+ */ -+static void -+opt_strcpy () -+{ -+ rtx_insn *insn, *next; -+ rtx_insn * x2reg = 0; -+ rtx_insn * reg2x; -+ unsigned int regno; -+ -+ 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 (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 -+ -+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)) -+ { -+ 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); -+ } -+#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) -+ { -+ hit = 1; -+ best_new_reg = new_reg; -+ } - } - 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 -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 reg_reg; -+ std::vector 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::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::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)) -+ { -+ /* 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 -+ { - -- 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); -+ SET_INSN_DELETED(x2reg); -+ SET_INSN_DELETED(insn); - -- df_insn_rescan (reg2x); -+ df_insn_rescan (reg2x); - -- } -+ ++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 -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 -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 -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 - #include - --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 insns; -+static std::vector jumps; -+static std::map insn2index; -+static std::vector 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> todo; -+ todo.push_back (std::make_pair (insns.size () - 1, ii)); -+ -+ int pass = 0; -+ while (!todo.empty ()) -+ { -+ std::pair 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::iterator i = jumps.begin (); i != jumps.end (); ++i) -+ { -+ if (JUMP_LABEL(*i) == insn) -+ { -+ std::map::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; -+ } -+ -+} - - /* - * #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 reg_reg; -+ unsigned current_label_index; -+ std::vector reg_reg; -+ std::vector 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::iterator i = reg_reg.begin (); -- i != reg_reg.end () && i + 1 != reg_reg.end ();) -+ for (std::vector::iterator i = reg_reg.begin (); i != reg_reg.end () && i + 1 != reg_reg.end (); -+ ) - { - bool inc = true; -- for (std::vector::iterator j = i + 1; j != reg_reg.end ();) -+ for (std::vector::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 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::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 -+ * -+ * set reg1, plus (reg2, const) -+ * set mem(reg2), y -+ * -+ * -> -+ * set reg1, reg2 -+ * set mem(reg1+), y -+ * -+ * if size of postinc == const -+ * -+ (insn 33 32 35 4 (set (reg/v/f:SI 8 a0 [orig:47 s ] [47]) -+ (plus:SI (reg/v/f:SI 9 a1 [orig:46 s ] [46]) -+ (const_int 1 [0x1]))) sn.c:5 141 {*addsi3_internal} -+ (nil)) -+ (insn 36 35 37 4 (set (mem:QI (reg/v/f:SI 9 a1 [orig:46 s ] [46]) [0 MEM[base: s_17, offset: 4294967295B]+0 S1 A8]) -+ (mem:QI (post_inc:SI (reg/v/f:SI 10 a2 [orig:53 s2 ] [53])) [0 MEM[base: s2_19, offset: 4294967295B]+0 S1 A8])) sn.c:5 46 {*m68k.md:1083} -+ (expr_list:REG_INC (reg/v/f:SI 10 a2 [orig:53 s2 ] [53]) -+ (nil))) -+ */ -+static unsigned -+commute_add_move (void) -+{ -+ unsigned change_count = 0; -+ -+ for (unsigned index = 0; index + 1 < insns.size (); ++index) -+ { -+ rtx_insn * insn = insns[index]; -+ rtx set = single_set (insn); -+ if (!set) -+ continue; -+ -+ rtx reg1 = SET_DEST(set); -+ if (!REG_P(reg1)) -+ continue; -+ -+ rtx plus = SET_SRC(set); -+ if (GET_CODE(plus) != PLUS) -+ continue; -+ -+ rtx reg2 = XEXP(plus, 0); -+ if (!REG_P(reg2)) -+ continue; -+ -+ rtx cnst = XEXP(plus, 1); -+ if (!CONST_INT_P(cnst)) -+ continue; -+ -+ rtx_insn * next = insns[index + 1]; -+ 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)) -+ 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 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 -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 -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 -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 - - /* 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> todo; - todo.push_back (std::make_pair (insns.size () - 1, ii)); - -@@ -236,53 +247,40 @@ filter_insns () - if (JUMP_LABEL(*i) == insn) - { - std::map::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 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; - } -+ -+ 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; -+ -+ 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 (!infos[index].get (REGNO(dst))) -+ { -+ fprintf (stderr, "eliminate dead assignment to %d:", REGNO(dst)); -+ debug_rtx (insn); -+ SET_INSN_DELETED(insn); -+ ++change_count; -+ } -+ } -+ 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 -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 - #include - --/* 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 insns; - static std::vector jumps; - static std::map insn2index; - static std::vector 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::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 -+ * -+ * move x,dx -+ * cmp dx,dy -+ * -+ * if dx and dy are both dead after compare. -+ * -+ * with -+ * -+ * sub #n,dx -+ * -+ d0 d1 d2 a0 a1 a7 (insn 99 59 41 7 (set (reg:SI 2 d2) -+ (const_int 1 [0x1])) sn.c:8 38 {*movsi_m68k} -+ (nil)) -+ d0 d1 d2 a0 a1 a7 (insn 41 99 42 7 (set (cc0) -+ (compare (reg/v:SI 1 d1 [orig:54 n ] [54]) -+ (reg:SI 2 d2))) sn.c:8 16 {*m68k.md:499} -+ (expr_list:REG_DEAD (reg:SI 2 d2) -+ (expr_list:REG_DEAD (reg/v:SI 1 d1 [orig:54 n ] [54]) -+ (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"); -+ -+ // maybe add a search? -+ rtx_insn * prev = insns[index - 1]; -+ rtx setp = single_set (prev); -+ if (!setp) -+ continue; -+ -+ rtx dstp = SET_DEST(setp); -+ if (!REG_P(dstp) || dstp != left) -+ continue; -+ -+ rtx srcp = SET_SRC(setp); -+ if (!CONST_INT_P(srcp)) -+ continue; -+ -+ int intval = -INTVAL(srcp); -+ if (intval < -8 || intval > 7) -+ 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); -+ -+ SET_SRC(setp) = srcp; -+ SET_DEST(setp) = dstp; -+ -+ 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))); -+ 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); -+ -+ 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); -+ -+ fprintf (stderr, ": replaced reg-reg compare with sub\n"); -+ debug_rtx(prev); -+ debug_rtx(insn); -+ -+ if (dstp != left) -+ { -+ // invert all conditions using this statement. -+ -+ } -+ -+ -+ ++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 -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; -+ } -+ -+ 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; - } -+ -+ inline bool contains(insn_info const & o) const { -+ if (o._def & ~_def) -+ return false; -+ if (o._use & ~_use) -+ return false; -+ return true; -+ } -+ -+ 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 (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; -+ -+ insn_info & ii0 = infos[pos++]; -+ if (!ii0.is_use(regno)) -+ return true; -+ -+ if (pos >= infos.size()) -+ return true; -+ -+ insn_info & ii1 = infos[pos]; -+ -+ return !ii1.is_use(regno); -+} -+ - /* - * 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); -+ } -+ -+ 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; -+ -+ 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 todo; -+ std::vector done; -+ done.resize(insns.size()); -+ todo.push_back (index + 1); - -- } -+ while (todo.size ()) -+ { -+ 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::iterator j = insn2index.find ((rtx_insn *) JUMP_LABEL(patchme)); -+ if (j != insn2index.end ()) -+ todo.push_back (j->second); -+ -+ rtx jmppattern = PATTERN (patchme); -+ -+ rtx jmpsrc = XEXP(jmppattern, 1); -+ if (GET_CODE(jmpsrc) == IF_THEN_ELSE) -+ { -+ 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)); -+ } -+ } -+ } -+ } - - ++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 -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::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; -+ -+ 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 todo; - std::vector 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 -+ add.l d1,a1 -+ subq.l #1,d1 -+ -> -+ move.l a0,a1 -+ subq.l #1,d1 -+ add.l d1,a1 -+ */ -+static unsigned -+merge_add (void) -+{ -+ unsigned change_count = 0; -+ for (unsigned index = 0; index + 2 < insns.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)) -+ continue; -+ -+ rtx set1 = single_set (ins1); -+ rtx set2 = single_set (ins2); -+ rtx set3 = single_set (ins3); -+ if (!set1 || !set2 || !set3) -+ 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)) -+ continue; -+ -+ CC_STATUS_INIT; -+ NOTICE_UPDATE_CC(PATTERN (ins2), ins2); -+ 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); -+ -+ 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; -+ -+ if (REGNO(dst1) != REGNO(dst2) || REGNO(r2) != REGNO(dst3)) -+ continue; -+ -+ fprintf (stderr, ": merge_add pattern found\n"); -+ -+ SET_SRC(set1) = l1; -+ remove_insn (ins2); -+ add_insn_after (ins2, ins3, 0); -+ } -+ return change_count; -+} -+ -+/* -+ * Always prefer lower register numbers within the class. -+ */ -+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 -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 -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 -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 - #include - -@@ -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) -+{ -+ if (REG_P(x)) -+ { -+ if (REGNO(x) == oldregno) -+ df_ref_change_reg_with_loc (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); -+ } -+} -+ -+static int -+bit2regno (unsigned bit) -+{ -+ if (!bit) -+ return -1; -+ -+ unsigned regno = 0; -+ while (!(bit & 1)) -+ { -+ ++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 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; -+ - if (validate_change (next, &SET_DEST(set2), newmem, 0)) - { -+ fprintf (stderr, ":bbb: commute_add_move found\n"); -+ - 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 found; -+ std::vector 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 ()) -+ { -+ 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)) -+ { -+ std::map::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); -+ } -+ 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::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, '*'); -+ -+ -+ 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 (); -+ -+// 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); -+ } -+ -+ if (strchr(flag_bbb_opts, 'X')) dump_insns ("bbb 1"); -+ clear (); -+ -+ return 0; -+ } -+ -+} // 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; -+ - 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); -+ } -+ - }; // class pass_regrename - - } // anon namespace - -From b747a5666a06f73ae8628788246f6d9e614f6393 Mon Sep 17 00:00:00 2001 -From: bebbo -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 insns; -+static std::vector temp; - static std::vector jumps; - static std::map insn2index; - static std::vector 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; -+ -+ 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) -+ { -+ 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_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); -+ } - } - } - -@@ -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 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; -+} -+ -+/** -+ * 1. scan for all used registers. -+ * 2. scan the stack from for omittable push/pop -+ * 3. adjust stack frame + insns referring to stack pointer -+ * typical code: -+ subq.l #4,sp -+ movem.l #16190,-(sp) -+ move.l 52(sp),d2 -+ move.l 56(sp),d3 -+ -+ * or -+ link a5,#4 -+ movem.l #16190,-(sp) -+ move.l 8(a5),d2 -+ move.l 12(a5),d3 -+ * -+ * => with a5 check only prolog/epilog -+ * => without a5 adjust insns referring sp if offset > startoffset + current sp diff -+ * -+ * 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) -+ /* nothing to do. */ -+ if (!insns.size ()) -+ return 0; -+ -+ temp.resize (insns.size ()); -+ -+ unsigned pos = 0; -+ rtx_insn * insn = insns[pos]; -+ if (JUMP_P(insn)) /* return -> empty function*/ -+ return 0; -+ -+ bool usea5 = false; -+ unsigned paramstart = 4; -+ /* -+ * 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) -+ break; -+ -+ rtx pattern = PATTERN (insn); -+ if (GET_CODE(pattern) == PARALLEL) -+ { -+ rtx set = XVECEXP(pattern, 0, 0); -+ rtx dst = SET_DEST(set); -+ /* ignore link a5 */ -+ if (REG_P(dst) && REGNO(dst) == 13) -+ usea5 = true; -+ else -+ { -+ /* use movem */ -+ temp[pos] = insn; -+ insns[pos] = 0; -+ } -+ ++pos; -+ continue; -+ } -+ if (GET_CODE(pattern) != SET) -+ { -+ ++pos; -+ continue; -+ } -+ -+ /* move only the push statements. */ -+ rtx src = SET_SRC(pattern); -+ rtx dest = SET_DEST(pattern); -+ if (REG_P(src)) -+ { -+ if (MEM_P(dest)) -+ { -+ rtx predec = XEXP(dest, 0); -+ if (GET_CODE(predec) == PRE_DEC) -+ { -+ rtx reg = XEXP(predec, 0); -+ if (REG_P(reg) && REGNO(reg) == 15) -+ { -+ temp[pos] = insn; -+ insns[pos] = 0; -+ } -+ } -+ } -+ } -+ else if (GET_CODE(src) == PLUS && REG_P(dest) && REGNO(dest) == 15) -+ { -+ /* 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)) -+ paramstart -= INTVAL(cx); -+ } -+ -+ if (++pos >= insns.size ()) -+ { -+ clear_temp (); -+ return 0; -+ } -+ } - -- std::vector found; -- std::vector 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 < 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) -+ 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) -+ { -+ insn = insns[pos]; -+ if (JUMP_P(insn)) /* return */ - break; - -- found.push_back (pos); -+ if (LABEL_P(insn)) -+ break; - -- /* follow jump and/or next insn. */ -- rtx_insn * insn = insns[index]; -- if (JUMP_P(insn)) -+ /* omitt the frame pointer a5. */ -+ rtx pattern = PATTERN (insn); -+ if (GET_CODE(pattern) == PARALLEL) - { -- std::map::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); -+ /* unlink is last. */ -+ if (REG_P(dst) && REGNO(dst) == 13) -+ break; -+ -+ /* movem. */ -+ temp[pos] = insn; -+ insns[pos] = 0; -+ } -+ else if (GET_CODE(pattern) == SET) -+ { -+ /* check for move (a7+), x */ -+ rtx src = SET_SRC(pattern); -+ rtx dst = SET_DEST(pattern); -+ if (REG_P(dst)) -+ { -+ if (MEM_P(src)) -+ { -+ rtx postinc = XEXP(src, 0); -+ if (GET_CODE(postinc) == POST_INC) -+ { -+ rtx reg = XEXP(postinc, 0); -+ if (REG_P(reg) && REGNO(reg) == 15) -+ { -+ temp[pos] = insn; -+ insns[pos] = 0; -+ } -+ } -+ } -+ } -+ } -+ } -+ ++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); -+ unsigned adjust = 0; -+ /* now all push/pop insns are in temp. */ -+ for (unsigned i = 0; i < temp.size (); ++i) -+ { -+ insn = temp[i]; -+ if (!insn) -+ continue; -+ -+ rtx pattern = PATTERN (insn); -+ /* check the pushed regs, either a vector or single statements */ -+ if (GET_CODE(pattern) == PARALLEL) -+ { -+ std::vector regs; -+ std::vector clobbers; -+ for (int j = 0; j < XVECLEN(pattern, 0); ++j) -+ { -+ rtx set = XVECEXP(pattern, 0, j); -+ if (GET_CODE(set) == CLOBBER) -+ { -+ clobbers.push_back (set); -+ continue; -+ } -+ rtx src = SET_SRC(set); -+ rtx dst = SET_DEST(set); -+ rtx reg; -+ if (MEM_P(src)) -+ reg = dst; -+ else if (MEM_P(dst)) -+ reg = src; -+ else -+ continue; -+ -+ if (i < prologueend) -+ paramstart += 4; -+ unsigned regbit = 1 << REGNO(reg); -+ if (freemask & regbit) -+ { -+ fprintf (stderr, i < prologueend ? "remove push for %d\n" : "remove pop for %d\n", REGNO(reg)); -+ if (i < prologueend) -+ adjust += 4; -+ } -+ else -+ regs.push_back (reg); -+ } -+ -+ /* don't touch - clobbers! */ -+ if (clobbers.size()) -+ continue; -+ -+ if ((int) regs.size () + 1 < XVECLEN(pattern, 0) || regs.size () <= 2) -+ { -+ if (regs.size () <= 2) -+ { -+ 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 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 set = gen_rtx_SET(reg, mem); -+ emit_insn_before (set, insn); -+ } -+ } -+ } -+ else -+ { -+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + 1)); -+ int x = regs.size () * 4 + 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); -+ -+ if (i >= prologueend) -+ x = 0; -+ -+ for (unsigned k = 0; k < regs.size (); ++k) -+ { -+ 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); -+ 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; -+ } -+ } -+ emit_insn_after (parallel, insn); -+ } -+ SET_INSN_DELETED(insn); -+ } -+ } -+ else -+ { -+ rtx set = PATTERN (insn); -+ -+ if (i < prologueend) -+ { -+ /* move x,-(a7). */ -+ paramstart += 4; -+ rtx src = SET_SRC(set); -+ unsigned regbit = 1 << REGNO(src); -+ if (freemask & regbit) -+ { -+ adjust += 4; -+ fprintf (stderr, "remove push for %d\n", REGNO(src)); -+ SET_INSN_DELETED(insn); -+ } -+ } -+ else -+ { -+ /* move (a7)+,x */ -+ rtx dst = SET_DEST(set); -+ unsigned regbit = 1 << REGNO(dst); -+ if (freemask & regbit) -+ { -+ fprintf (stderr, "remove pop for %d\n", REGNO(dst)); -+ SET_INSN_DELETED(insn); -+ } - } -- 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::iterator i = found.begin (); i != found.end (); ++i) -- do_reg_rename (PATTERN (insns[*i]), oldregno, newregno); -+ rtx set = single_set (insn); -+ if (!set) -+ 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 plus = XEXP(mem, 0); -+ if (GET_CODE(plus) == PLUS) -+ { -+ rtx sp = XEXP(plus, 0); -+ if (REG_P(sp) && REGNO(sp) == 15) -+ { -+ 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); -+ } -+ } -+ } -+ } - } - } -+ -+ /* restore stack insns */ -+ clear_temp (); -+ - 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 (); -+ } -+ -+ 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 -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 - #include - -@@ -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; -+ -+ 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 char fxname[512]; -+ if (current_function_decl == NULL) -+ strcpy (fxname, ""); -+ else -+ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2)); -+ return fxname; -+} -+ - 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)) -+ { -+ 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); -+ } - - // 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); -+ -+ infos[pos] = def | use | ii; -+ -+ 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; -+ - /* - * 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) -+ { -+ usea5 = true; -+ set = XVECEXP(pattern, 0, 2); -+ a5offset = INTVAL(XEXP(SET_SRC(set), 1)); -+ } - 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; -+ - /* search epilogues - there can be multiple epilogues. */ - while (pos < insns.size ()) - { -@@ -1406,6 +1451,7 @@ shrink_stack_frame (void) - ++pos; - } - -+ - /* 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; -+ -+ 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. -+ */ -+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 found; -+ std::vector 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::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::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; -+} -+ -+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 = "*"; -+ -+ return TARGET_AMIGA && optimize > 0 && flag_bbb_opts; - } - - virtual unsigned int -@@ -1704,6 +1871,10 @@ 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 (); -@@ -1749,6 +1920,11 @@ namespace - { - class opt_pass * rr = ::global_pass_regrename->clone (); - rr->execute (0); -+ -+// update_insns (); -+// update_insn_infos (); -+// bb_reg_rename (); -+ - update_insns (); - } - - -From 56aa60f1154c2988edf35ba30ec259a798ba61f2 Mon Sep 17 00:00:00 2001 -From: bebbo -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]; -+ { -+ 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; -+ 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 - -+ -+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); - -From 51c5b7b668483ac0cdc30a3fee718754a03bcca9 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 - #include - -+static bool be_verbose; -+ -+extern struct lang_hooks lang_hooks; -+extern tree current_function_decl; -+static tree last_function_decl; -+static char const * -+getCurrentFunctionName () -+{ -+ static char fxname[512]; -+ if (current_function_decl == NULL) -+ strcpy (fxname, ""); -+ else -+ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2)); -+ return fxname; -+} -+ -+static int -+log (char const * fmt, ...) -+{ -+ if (!be_verbose) -+ return 0; -+ -+ va_list args; -+ va_start(args, fmt); -+ if (last_function_decl != current_function_decl) -+ { -+ 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) - } - } - --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 () - } - } - --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, ""); -- 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"); - - SET_INSN_DELETED(insn); - -@@ -1130,7 +1137,7 @@ const_cmp_to_sub (void) - SET_INSN_DELETED(prev); - prev = emit_insn_before (neuprev, insn); - -- 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"); - - if (dstp != left) - { -@@ -1191,7 +1198,7 @@ const_cmp_to_sub (void) - - 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) - - if (is_reg_dead (REGNO(dst), index)) - { -- 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; - -- fprintf (stderr, ":bbb: merge_add applied\n"); -+ log ("merge_add applied\n"); -+ -+ rtx_insn * newins1 = make_insn_raw(gen_rtx_SET(dst1, l1)); -+ add_insn_after (newins1, ins1, 0); -+ SET_INSN_DELETED(ins1); - -- 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); - } - return change_count; - } -@@ -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; - } - --/* -- * 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 found; -- std::vector 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::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::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; --} -- --extern const char * current_function_func_begin_label; - extern class opt_pass * global_pass_regrename; - - namespace -@@ -1848,10 +1762,10 @@ namespace - virtual bool - gate (function *) - { -- if (!flag_bbb_opts) -- flag_bbb_opts = "*"; -+ if (!string_bbb_opts) -+ string_bbb_opts = "+"; - -- return TARGET_AMIGA && optimize > 0 && flag_bbb_opts; -+ return TARGET_AMIGA && optimize > 0 && string_bbb_opts && !strchr (string_bbb_opts, '-'); - } - - 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 (); -+ } - -- update_insns (); -+ if (done) -+ break; - } - - if (do_shrink_stack_frame) -@@ -1938,8 +1853,8 @@ namespace - update_insns (); - } - -- 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, - - /* 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); - - 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 -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 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/.project b/.project -index ab5c4b198d08..22b8c5a11f48 100644 ---- .project -+++ .project -@@ -5,7 +5,23 @@ - - - -+ -+ org.eclipse.cdt.managedbuilder.core.genmakebuilder -+ clean,full,incremental, -+ -+ -+ -+ -+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder -+ full,incremental, -+ -+ -+ - - -+ org.eclipse.cdt.core.cnature -+ org.eclipse.cdt.core.ccnature -+ org.eclipse.cdt.managedbuilder.core.managedBuildNature -+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - -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 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -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 -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); - } - 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 *); - #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]); -+ } -+#endif -+ return r; -+} - -From f6379a10611d6376109a63b65768387905a30490 Mon Sep 17 00:00:00 2001 -From: bebbo -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]; --} -+/* 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, othercum; -+ -+/* 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 = decl == current_function_decl ? &mycum : &othercum; -+ *cump = (int)cum; -+ 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 = *(struct amigaos_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 (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 (struct amigaos_args * cum, machine_mode mode, const_tree type) -+{ -+ DPRINTF(("m68k_function_arg numOfRegs=%d\r\n", cum ? cum->num_of_regs : 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) -+{ -+ DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p)); -+ -+ struct amigaos_args *cum = *(struct amigaos_args **) get_cumulative_args (cum_v); -+ -+ 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; -+ } -+ cum->regs_already_used |= (1 << (cum->last_arg_reg + i)); -+ } -+ return gen_rtx_REG (mode, cum->last_arg_reg); -+ } -+ return _m68k_function_arg (cum, mode, type); -+} -+ -+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))); -+ } -+} -+ -+ -+/* 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]; -+} -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 -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 -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 -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_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 = ®_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 (); -+ - regrename_init (false); - - regrename_analyze (NULL); - -From 23951fbf9ef78f3106624afd857e738ee56d3663 Mon Sep 17 00:00:00 2001 -From: bebbo -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))); -+ { -+ 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 -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 -+#include - #include - - 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; -+ } -+ - 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; -+ -+ 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; -+ -+ return mask & ~_use; - } - }; - -@@ -271,6 +293,7 @@ do_reg_rename (rtx x, unsigned oldregno, unsigned newregno) - * Collect some data. - */ - static std::vector insns; -+static std::vector proepilogue; - static std::vector temp; - static std::vector jumps; - static std::map 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); -+ -+ if (JUMP_P(insn)) -+ inproepilogue = false; -+ } -+ -+ 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; -+ - infos[pos] = def | use | ii; - - ii &= ~def; -@@ -558,6 +619,114 @@ update_insn_infos (void) - } - } - -+static int -+bit2regno (unsigned bit) -+{ -+ if (!bit) -+ return -1; -+ -+ unsigned regno = 0; -+ while (!(bit & 1)) -+ { -+ ++regno; -+ bit >>= 1; -+ } -+ 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) -+ { -+ insn_info & ii = infos[index]; -+ const unsigned def = ii._def & ~ii._hard; -+ unsigned mask = ii.get_free_mask (); -+ -+ if (!mask || !def) -+ continue; -+ -+ std::set found; -+ std::vector 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::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::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); -+ -+ 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 = ®_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 -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); -+ -+ /* 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; -+ } -+ - 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> & 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 (fmt[i] == 'e') -+ { -+ 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> 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 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) -+ { -+ 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::iterator i = found.begin (); i != found.end (); ++i) -+ /* check the renamed insns. */ -+ std::vector> locs; -+ bool ok = true; -+ std::vector patch; -+ for (std::set::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>::iterator j = locs.begin (); j != locs.end (); ++j) -+ { -+ debug_rtx (*j->first); -+ debug_rtx (j->second); -+ } -+ ok = false; -+ } -+ -+ for (std::vector>::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>::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 ()); -+ -+ for (std::vector::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); -+ } -+ -+// 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 -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 -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> & loc, rtx x, unsigned oldregno, unsigned newregno) -+temp_reg_rename (std::vector> & loc, rtx x, unsigned oldregno, unsigned newregno) - { - RTX_CODE code = GET_CODE(x); - -@@ -322,44 +349,17 @@ validate_rename (std::vector> & 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> locs; -+ std::vector> patch; - bool ok = true; -- std::vector patch; -+ - for (std::set::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>::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>::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>::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::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>::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 -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> & loc, rtx x, unsigned oldre - * Collect some data. - */ - static std::vector insns; --static std::vector proepilogue; -+static std::vector proepilogue; - static std::vector temp; - static std::vector jumps; - static std::map 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> 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>::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 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::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::iterator i = a5pos.begin (); i != a5pos.end (); ++i) -+ SET_INSN_DELETED(temp[*i]); -+ } -+ } -+ - /* 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 -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 -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 -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> & loc, rtx x, unsigned oldregno, unsigned newregno) -+temp_reg_rename (std::vector > & 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> todo; -+ std::vector > 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> locs; -- std::vector> patch; -+ std::vector > locs; -+ std::vector > patch; - bool ok = true; - - for (std::set::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>::iterator j = locs.begin (); j != locs.end (); ++j) -+ for (std::vector >::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>::iterator j = patch.begin (); j != patch.end (); ++j) -+ for (std::vector >::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 -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 -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 -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 -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 -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) -+ { -+ if (TREE_CODE (*node) == VAR_DECL) -+ { -+ if (is_attribute_p ("chip", name)) - #ifdef TARGET_ASM_NAMED_SECTION -- { -- if (! TREE_STATIC (*node) && ! DECL_EXTERNAL (*node)) -+ { -+ 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"); -+ } -+ } -+ } - #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) -+ { -+ 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 -+ "\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) -+ { -+ 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) -+ "\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 -+ "\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); --} -+ fsize); -+ } - - //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 (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")); -+ -+ 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 -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 > & loc, rtx x, unsigned oldregno, unsigned newregno) - { -+ if (!x) -+ return; -+ - RTX_CODE code = GET_CODE(x); ++++ .cproject +@@ -0,0 +1,188 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/.project b/.project +new file mode 100644 +index 000000000000..500c9ee08dca +--- /dev/null ++++ .project +@@ -0,0 +1,34 @@ ++ ++ ++ gcc-6 ++ ++ ++ ++ ++ ++ org.eclipse.cdt.managedbuilder.core.genmakebuilder ++ clean,full,incremental, ++ ++ ++ ++ ++ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder ++ full,incremental, ++ ++ ++ ++ ++ ++ org.eclipse.cdt.core.cnature ++ org.eclipse.cdt.core.ccnature ++ org.eclipse.cdt.managedbuilder.core.managedBuildNature ++ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature ++ ++ ++ ++ build-gcc ++ 2 ++ D:/develop/workspaces/c1/amigaos-cross-toolchain/.build-m68k/build/gcc-6 ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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. - const char *fmt = GET_RTX_FORMAT(code); -@@ -542,6 +544,7 @@ update_insn_infos (void) - if (pass && infos[pos].contains (ii)) - break; +-timestamp='2016-01-01' ++timestamp='2017-04-21' -+ ii._hard = 0; - ii |= infos[pos]; + # 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 51e2bc86e9a4..4aedf54bab12 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 \ +@@ -1986,7 +1987,7 @@ gcc-nm.c: gcc-ar.c + cp $^ $@ - 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; - } + COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o \ +- collect-utils.o file-find.o hash-table.o ++ collect-utils.o file-find.o hash-table.o $(EXTRA_COLLECT2_OBJS) + 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 -+static unsigned -+find_start (std::set & found, unsigned start, unsigned rename_regno) + # 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 +--- /dev/null ++++ gcc/amigacollect2.c +@@ -0,0 +1,348 @@ ++/* 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_error(location_t, const char *, ...); ++void fork_execute(const char *, char **, bool); ++ ++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 +{ -+ /* search the start. */ -+ while (start < 0) -+ { -+ unsigned startm1 = start - 1; ++ struct liblist *next; ++ char *name; ++ char *cname; ++}; + -+ /* already searched. */ -+ if (found.find (startm1) != found.end ()) -+ break; ++/* Not zero if "-static" was specified on GCC command line or if all the ++ libraries are static. */ ++static int flag_static=0; + -+ /* do not run over RETURNS */ -+ rtx_insn * before = insns[startm1]; -+ if (JUMP_P(before) && ANY_RETURN_P(PATTERN (before))) -+ break; ++/* 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; + -+ start = startm1; ++/* Not zero if some of the specified libraries are dynamic. */ ++static int found_dynamic_libs=0; + -+ /* found the definition without use. */ -+ insn_info & jj = infos[start]; -+ if (jj.is_def (rename_regno) && !jj.is_use (rename_regno)) -+ break; ++/* 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++; + } -+ return start; +} + - /* - * 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); ++/* Add a library to the list of dynamic libraries. First make sure that the ++ library is actually dynamic. Used by "amigaos_libname_hook()". */ + - /* 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); ++static void ++add_lib (const char *name) ++{ ++ struct liblist *lib; ++ static char buf[256]; + -+ /* for each jump to this label: -+ * check if the reg was used at that jump. -+ * if used, find def -+ */ -+ for (std::vector::iterator i = jumps.begin (); i != jumps.end (); ++i) -+ { -+ if (JUMP_LABEL(*i) == insn) -+ { -+ std::map::iterator j = insn2index.find (*i); -+ if (j == insn2index.end ()) -+ continue; ++ for (lib = head; lib; lib = lib->next) ++ if (!strcmp(lib->name, name)) ++ return; + -+ unsigned start = j->second; -+ if (!infos[start].is_use (rename_regno)) -+ continue; ++ /* 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. */ + -+ start = find_start (found, start, rename_regno); -+ todo.push_back (start); -+ } -+ } ++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_error (input_location, "%s", fname); ++ while (!feof(in) && (bytes = fread(buf, 1, BUFSIZE, in))) ++ fwrite(buf, 1, bytes, x); ++ fclose(in); ++} + - 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::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 >::iterator j = patch.begin (); j != patch.end (); ++j) - -From ee7031d5d1442ca1e933b3cb029f91ba1534354d Mon Sep 17 00:00:00 2001 -From: bebbo -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 & 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 -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; - ++/* 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. */ + - #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) ++void ++amigaos_prelink_hook (const char **ld1_argv, int *strip_flag) +{ -+ if (0 == strncmp(".text", name, 5)) -+ name = ".text"; ++ if (flag_static) ++ return; + -+ 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 ++ 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; + - - /* 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) ++ /* 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=(char*) ++ 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=(char*)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; ++ } ++ } + -+#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 - ++ out = fopen(XLIBS_C_NAME, "w"); ++ if (out == NULL) ++ fatal_error (input_location, "%s", XLIBS_C_NAME); ++ x = fopen(SHARED_X_NAME, "w"); ++ if (x == NULL) ++ fatal_error (input_location, "%s", SHARED_X_NAME); + - /* 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 -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(-) - ++ 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, false); ++ ++ /* 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_error (input_location, "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, false); ++} diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c -index 3e6c316149b0..407e2f74fd9f 100755 ---- gcc/bbb-opts.c +new file mode 100755 +index 000000000000..9e989e9b1ec0 +--- /dev/null +++ gcc/bbb-opts.c -@@ -738,123 +738,124 @@ opt_reg_rename (void) - if (!mask) - continue; - -- std::set found; -+ /* first = pos to start, second indicates to treat def as use. */ - std::vector todo; -+ std::set 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::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); +@@ -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. ++ ++ 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. ++ ++ You should have received a copy of the GNU General Public License ++ along with GCC; see the file COPYING3. If not see ++ . */ ++ ++/** ++ * 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 "backend.h" ++#include "target.h" ++#include "rtl.h" ++#include "tm_p.h" ++#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 ++#include ++#include ++ ++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; ++static char fxname[512]; ++static char const * ++get_current_function_name () ++{ ++ if (current_function_decl == NULL) ++ strcpy (fxname, ""); ++ else ++ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2)); ++ return fxname; ++} ++ ++/* a simple log to stdout. */ ++static int ++log (char const * fmt, ...) ++{ ++ if (!be_verbose) ++ return 0; ++ ++ va_list args; ++ va_start(args, fmt); ++ if (last_function_decl != current_function_decl) ++ { ++ 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; ++} ++ ++enum proepis ++{ ++ IN_CODE, IN_PROLOGUE, IN_EPILOGUE, IN_EPILOGUE_PARALLEL_POP ++}; ++ ++/** ++ * What's needed to track values? ++ */ ++class track_var ++{ ++ 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)]; ++ unsigned mr = mask[REGNO(x)]; ++ /* try to expand the register. */ ++ if (v) ++ { ++ if (dstMode != GET_MODE(v) && (GET_CODE(v) != CONST_INT || mr == (1 << FIRST_PSEUDO_REGISTER))) ++ return false; ++ ++ *mask |= mr; ++ *z = v; ++ return true; ++ } ++ ++ /* store the reg otherwise. */ ++ *mask |= (1 << REGNO(x)); ++ if (GET_MODE(x) == dstMode) ++ *z = x; ++ else ++ *z = gen_rtx_REG (dstMode, REGNO(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; ++ } ++ default: ++ return false; ++ } ++ break; ++ } ++ default: ++ return false; ++ } ++ } + -+ /* for each jump to this label: -+ * check if the reg was used at that jump. -+ * if used, find def -+ */ -+ for (std::vector::iterator i = jumps.begin (); i != jumps.end (); ++i) - { -- std::map::iterator j = insn2index.find (*i); -- if (j == insn2index.end ()) -- continue; -+ if (JUMP_LABEL(*i) == insn) -+ { -+ std::map::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::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::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 -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 -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; - } - ++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; ++ } ++ } ++ ++ 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 -+ scan_call (rtx_insn *); ++ 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; ++ } ++ } ++ } ++ } + - void - scan (rtx); - -@@ -267,6 +269,31 @@ struct insn_info - } - }; - -+void -+insn_info::scan_call (rtx_insn * insn) ++ rtx ++ get (unsigned regno) ++ { ++ if (regno >= FIRST_PSEUDO_REGISTER) ++ return 0; ++ ++ return value[regno]; ++ } ++ ++ void ++ set (machine_mode mode, unsigned regno, rtx x, unsigned index) ++ { ++ 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); ++ } ++ } ++ ++ bool ++ equals (unsigned regno, rtx x) ++ { ++ if (regno >= FIRST_PSEUDO_REGISTER) ++ 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]); ++ } ++ ++ void ++ clear (machine_mode mode, unsigned regno, unsigned index) ++ { ++ if (regno >= FIRST_PSEUDO_REGISTER) ++ return; ++ ++ 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 ++ 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); ++ } ++ } ++ ++ 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; ++ } ++ } ++ } ++ ++ /* 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; ++ } ++}; ++ ++/* 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 +{ -+ /* add mregparm registers. */ -+ for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1)) -+ { -+ rtx op, reg; ++ rtx_insn * insn; // the insn + -+ 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; ++// 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 ++ ++ enum proepis proepi; ++ ++ bool stack; // part of stack frame insns ++ ++// 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; + -+ scan (PATTERN (insn)); ++ machine_mode mode; + -+ /* mark scratch registers. */ -+ def (0); -+ def (1); -+ def (8); -+ def (9); ++ 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; + -+} ++ bool visited; + - /* 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; -+} ++ int sp_offset; + -+/* -+ * search backward and find the initial assignment for that regno. -+ */ - static unsigned - find_start (std::set & 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; -+ } ++ int dst_autoinc; ++ int src_autoinc; + -+ std::vector fixups; ++// values for all variables - if used ++ track_var * track; + -+ /* 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 fixups; -+ std::vector::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::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); ++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) ++ { ++ } + -+ 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; ++ track_var * ++ get_track_var (); + -+ 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 -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 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::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; ++ inline ptrdiff_t ++ operator < (insn_info const & o) const ++ { ++ return this - &o; ++ } + -+ rtx plus = gen_rtx_PLUS(mode, copy_reg (reg, -1), gen_rtx_CONST_INT (mode, intval)); ++ int ++ get_index () const; + -+ rtx_insn * neuprev = make_insn_raw (gen_rtx_SET(copy_reg (reg, -1), plus)); ++ void ++ plus_to_move (rtx_insn * newinsn); + -+ 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; ++ void ++ swap_adds (rtx_insn * newinsn, insn_info & ii); + -+ // 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); ++ void ++ absolute2base (unsigned regno, unsigned base, rtx with_symbol); + -+ SET_INSN_DELETED(prev); -+ prev = emit_insn_before (PATTERN (neuprev), insn); ++ rtx ++ make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool apply); + -+ 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 -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 -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 - #include - #include - --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 ++ inline bool ++ is_compare () const ++ { ++ return compare; ++ } + -+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; ++ inline machine_mode ++ get_mode () const ++ { ++ return mode; + } + + inline bool -+ is_empty () ++ is_dst_reg () const + { -+ 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); ++ return dst_reg; + } + -+ inline unsigned -+ get_use () const ++ inline bool ++ is_dst_mem () const + { -+ return use; ++ return dst_mem; + } -+ inline unsigned -+ get_def () const ++ ++ inline bool ++ is_src_mem () const + { -+ return def; ++ return src_mem; + } -+ inline unsigned -+ get_hard () const ++ ++ inline bool ++ is_src_mem_2nd () 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; ++ return src_2nd && src_mem; + } + -+ inline insn_info & -+ drop_def () ++ inline bool ++ has_dst_memreg () const + { -+ 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; -+ } ++ return dst_mem_reg; ++ } + + 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 () ++ has_src_memreg () const + { -+ hard = use | def; -+ return *this; ++ return src_mem_reg; + } + -+ 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; ++ inline rtx ++ get_dst_symbol () const ++ { ++ return dst_symbol; + } + -+ unsigned -+ get_regbit () const ++ inline rtx ++ get_src_symbol () 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) -+{ -+ -+ auto i = insn2index.find (insn); -+ if (i == insn2index.end ()) -+ return; ++ return src_symbol; ++ } ++ inline bool ++ has_dst_addr () const ++ { ++ return dst_mem_addr; ++ } + -+ insn_info & ii = infos[i->second]; ++ inline bool ++ has_src_addr () const ++ { ++ return src_mem_addr; ++ } + -+ fprintf (f, "\n\t\t\t\t\t\t| "); ++ inline bool ++ is_label () const ++ { ++ return label; ++ } + -+ 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, " "); ++ inline bool ++ is_jump () const ++ { ++ return jump; ++ } + -+ 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, " "); ++ inline bool ++ is_call () const ++ { ++ return call; ++ } + -+ if (ii.is_use (FIRST_PSEUDO_REGISTER)) -+ fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "*cc " : "cc "); ++ inline unsigned ++ get_dst_mem_addr () const ++ { ++ return dst_mem_addr; ++ } + -+} ++ inline unsigned ++ get_src_mem_addr () const ++ { ++ return src_mem_addr; ++ } + - /* - * 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 (); ++ inline bool ++ is_src_reg () const ++ { ++ return src_reg && !src_op; ++ } + -+ 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 (); ++ inline int ++ get_src_op () const ++ { ++ return src_op; ++ } + - 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); ++ inline bool ++ is_src_ee () const ++ { ++ return src_ee; ++ } + - /* 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 -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) ++ is_src_mem_plus () const + { -+ return (myuse & (1 << regno)) != 0; ++ return src_mem && src_plus; + } + - 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 -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 ++ inline bool ++ is_dst_mem_plus () const ++ { ++ return dst_mem && dst_plus; ++ } ++ ++ inline int ++ get_dst_regno () const ++ { ++ return dst_reg ? REGNO(dst_reg) : -1; ++ } ++ ++ inline int ++ get_src_regno () const ++ { ++ return src_reg ? REGNO(src_reg) : -1; ++ } ++ ++ inline rtx ++ get_src_reg () const ++ { ++ return src_reg; ++ } + -+ 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) ++ inline rtx ++ get_dst_reg () const ++ { ++ return dst_reg; ++ } ++ ++ inline int ++ get_src_mem_regno () const ++ { ++ 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; ++ } ++ ++ inline rtx ++ get_src_mem_reg () const ++ { ++ return src_mem_reg; ++ } ++ ++ inline rtx ++ get_dst_mem_reg () const ++ { ++ return dst_mem_reg; ++ } ++ ++ inline int ++ get_src_intval () const ++ { ++ return src_intval; ++ } ++ ++ inline int ++ get_dst_intval () const ++ { ++ return dst_mem_addr; ++ } ++ ++ 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; + } + ++ void ++ fledder (rtx set); ++ ++ void ++ fledder_src_mem (rtx src); ++ + /* update usage. */ + void + update (insn_info & o) @@ -21615,6683 +1518,2547 @@ index 439223bf6f87..fc4acc87a0a9 100755 + + bool + is_stack () const -+ { -+ return stack; -+ } -+ -+ inline int -+ in_proepi () const - { -+ return proepi; - } - - inline void -@@ -487,12 +526,9 @@ temp_reg_rename (std::vector > & loc, rtx x, unsigned oldr - /* - * Collect some data. - */ --static std::vector insns; --static std::vector proepilogue; --static std::vector temp; -+static std::vector infos; - static std::vector jumps; - static std::map insn2index; --static std::vector infos; - - /* - * Reset collected data. -@@ -500,8 +536,6 @@ static std::vector 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 > 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::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 & 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 todo; - std::set 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::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::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 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::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 todo; - std::vector 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 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::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::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 -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 ++ { ++ return stack; ++ } + -+ // 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 ++ inline enum proepis ++ in_proepi () const ++ { ++ return proepi; ++ } + - int proepi; // 1 = in prologue, 2 = in epilogue, 0 = other ++ inline void ++ set_proepi (enum proepis p) ++ { ++ proepi = p; ++ } + - 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; ++ 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; + -+ int dst_regno; -+ int dst_mem_reg; -+ unsigned dst_mem_addr; ++ mode = VOIDmode; + -+ int src_regno; -+ int src_mem_regno; -+ unsigned src_intval; ++ dst_reg = 0; ++ dst_mem_reg = 0; ++ dst_symbol = 0; ++ src_reg = 0; ++ src_mem_reg = 0; ++ src_symbol = 0; ++ dst_mem_addr = 0; + - 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) ++ src_intval = 0; ++ src_mem_addr = 0; ++ ++ dst_autoinc = 0; ++ src_autoinc = 0; ++ } ++ ++ inline int ++ get_src_autoinc () const + { ++ return src_autoinc; + } + -+ inline void -+ plus_to_move (rtx_insn * newinsn) ++ inline int ++ get_dst_autoinc () const + { -+ insn = newinsn; -+ dst_plus = false; -+ dst_reg = true; -+ // usage flags did not change ++ return dst_autoinc; + } + + inline bool -+ is_dst_reg () const ++ is_empty () + { -+ return dst_reg; ++ return !def && !use && !hard; ++ } ++ ++ inline void ++ mark_myuse (int regno) ++ { ++ myuse |= 1 << regno; ++ use |= 1 << regno; ++ } ++ ++ inline void ++ mark_use (int regno) ++ { ++ use |= 1 << regno; ++ } ++ ++ inline void ++ mark_def (int regno) ++ { ++ def |= 1 << regno; ++ } ++ ++ inline void ++ mark_hard (int regno) ++ { ++ hard |= 1 << regno; ++ } ++ ++ inline void ++ unset (int regno) ++ { ++ use &= ~(1 << regno); ++ def &= ~(1 << regno); ++ hard &= ~(1 << regno); ++ } ++ ++ inline unsigned ++ get_use () const ++ { ++ return use; ++ } ++ ++ inline unsigned ++ get_myuse () const ++ { ++ return myuse; ++ } ++ ++ inline void ++ set_use (unsigned u) ++ { ++ use = u; ++ } ++ ++ inline unsigned ++ get_def () const ++ { ++ return def; ++ } ++ inline unsigned ++ get_hard () const ++ { ++ return hard; + } + + inline bool -+ is_src_reg () const ++ is_use (int regno) + { -+ return src_reg; ++ return (use & (1 << regno)) != 0; + } + -+ inline int -+ get_dst_regno () const ++ inline bool ++ is_myuse (int regno) + { -+ return dst_regno; ++ return (myuse & (1 << regno)) != 0; + } + -+ inline int -+ get_src_regno () const ++ inline bool ++ is_def (int regno) + { -+ return src_regno; ++ return (def & (1 << regno)) != 0; + } + + inline bool -+ is_src_plus () const ++ is_hard (int regno) ++ { ++ return (hard & (1 << regno)) != 0; ++ } ++ ++ inline void ++ clear_hard_def () ++ { ++ hard = 0; ++ def = 0; ++ } ++ ++ /* ++ * 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; ++ } ++ ++ 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; ++ } ++ ++ inline insn_info & ++ or_use (insn_info const & o) ++ { ++ use |= o.myuse | o.def | o.hard; ++ return *this; ++ } ++ ++ inline insn_info & ++ drop_def () ++ { ++ use &= ~def; ++ return *this; ++ } ++ ++ inline insn_info & ++ make_hard () ++ { ++ hard = use | def; ++ return *this; ++ } ++ ++ inline insn_info & ++ make_clobber () + { -+ return src_plus; ++ hard = use = def = use | def; ++ return *this; + } + + inline bool -+ is_src_const () const - { -+ return src_const; - } - ++ 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; ++ } ++ ++ inline int ++ get_sp_offset () const ++ { ++ return sp_offset; ++ } ++ + inline void -+ mark_jump () ++ set_sp_offset (int sp) + { -+ jump = true; ++ sp_offset = sp; ++ } ++ ++ inline bool ++ is_visited () const ++ { ++ return visited; + } ++ + inline void -+ mark_call () ++ mark_visited () + { -+ call = true; ++ visited = true; + } ++ + inline void -+ mark_label () ++ clear_visited () + { -+ label = true; ++ visited = false; + } + + void -+ fledder (rtx set); ++ scan (); ++ ++ void ++ scan_rtx (rtx); ++ ++ bool ++ make_post_inc (int regno); ++ ++ void ++ auto_inc_fixup (int regno, int size); + - /* 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); ++ /* return bits for alternate free registers. */ ++ unsigned ++ get_free_mask () const ++ { ++ if (def & hard) ++ return 0; + -+ if (dst == cc0_rtx) -+ { -+ compare = true; -+ set = src; -+ dst = SET_DEST(set); -+ src = SET_SRC(set); -+ } ++ if (!def) ++ return 0; + -+ 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); -+ } -+ } -+ } ++ unsigned def_no_cc = def & ~(1 << FIRST_PSEUDO_REGISTER); ++ if (def_no_cc > 0x4000) ++ return 0; + -+ 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); -+ } -+ } -+ } ++ 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; + - /* 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"); ++ return mask & ~use; ++ } + - } - - /* -@@ -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 (); ++ unsigned ++ get_regbit () const ++ { ++ if (GET_MODE_SIZE(mode) > 4) ++ return 0; ++ return def & ~hard & ~use & 0x7fff; ++ } + -+ char inproepilogue = 1; -+ /* create a vector with relevant insn. */ -+ for (insn = get_insns (); insn; insn = next) -+ { -+ next = NEXT_INSN (insn); ++ void ++ set_insn (rtx_insn * newinsn); + -+ if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn)) -+ { ++ void ++ a5_to_a7 (rtx a7); ++}; + -+ insn2index.insert (std::make_pair (insn, infos.size ())); -+ infos.push_back (insn_info (insn, inproepilogue)); -+ insn_info & ii = infos[infos.size () - 1]; ++bool ++insn_info::make_post_inc (int regno) ++{ ++ rtx pattern = PATTERN (insn); ++ rtx_insn * new_insn = make_insn_raw (pattern); + -+ if (JUMP_P(insn)) -+ { -+ jumps.push_back (insn); -+ inproepilogue = 0; ++ // convert into POST_INC ++ rtx set0 = single_set (new_insn); ++ if (!set0) ++ return false; + -+ 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); -+ } -+ } ++ rtx set = set0; + -+ 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 (); -+} ++ if (is_compare ()) ++ set = SET_SRC(set); ++ rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set); + - /* 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; -+ } ++ 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); ++ } + -+ 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); ++ rtx reg = XEXP(mem, 0); + -+ 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 -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; ++ XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg); + -+ void -+ plus_to_move (rtx_insn * newinsn); ++ if (insn_invalid_p (new_insn, 0)) ++ { ++ XEXP(mem, 0) = reg; ++ insn_invalid_p (insn, 0); ++ return 0; ++ } + -+ void -+ swap_adds(rtx_insn * newinsn, insn_info & ii); - - inline bool - is_dst_reg () const -@@ -715,7 +712,69 @@ temp_reg_rename (std::vector > & loc, rtx x, unsigned oldr - */ - static std::vector infos; - static std::vector jumps; --static std::map insn2index; -+static std::map insn2index; ++ 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); + -+static insn_info * info0; ++ return 1; ++} + -+static void -+update_insn2index () ++static rtx ++add_clobbers (rtx_insn * oldinsn) +{ -+ 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) ++ 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--) + { -+ insn_info & ii = infos[i]; -+ insn2index.insert (std::make_pair (ii.get_insn (), &ii)); ++ rtx x = XVECEXP(pattern, 0, j); ++ if (GET_CODE(x) == CLOBBER) ++ ++num_clobbers; + } -+ info0 = &infos[0]; ++ ++ 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; +} + -+int -+insn_info::get_index () const ++void ++insn_info::auto_inc_fixup (int regno, int size) +{ -+ insn_info * ii = &infos[0]; ++// debug_rtx (insn); ++ rtx set0 = single_set (insn); ++ rtx set = set0; ++ if (is_compare ()) ++ set = SET_SRC(set); + -+ if (ii == info0) ++ // add to register ++ if (get_src_regno () == regno) + { -+ ptrdiff_t diff = ((char const *) this - (char const *) ii); -+ unsigned pos = diff / sizeof(insn_info); -+ if (pos < infos.size ()) -+ return pos; ++ 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); + -+ // realloc happened... -+ for (unsigned i = 0; i < infos.size (); ++i) -+ if (infos[i].get_insn () == this->insn) -+ return i; ++ 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); ++ } + -+ // whoops!? -+ return 0; ++ 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); ++ } ++ ++ rtx pattern = add_clobbers (insn); ++ ++ SET_INSN_DELETED(insn); ++ insn = emit_insn_after (pattern, insn); +} + -+void -+insn_info::plus_to_move (rtx_insn * newinsn) ++track_var * ++insn_info::get_track_var () +{ -+ insn = newinsn; -+ src_plus = false; -+ src_reg = true; -+ insn2index.insert(std::make_pair(insn, this)); -+ // usage flags did not change ++ if (!track) ++ track = new track_var (); ++ return track; +} + +void -+insn_info::swap_adds(rtx_insn * newinsn, insn_info & ii) ++insn_info::scan () +{ -+ insn = newinsn; ++ 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; + -+ std::swap(*this, ii); ++ 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); ++} + -+ insn2index.insert(std::make_pair(insn, this)); -+ insn2index.insert(std::make_pair(ii.insn, &ii)); ++/* 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; ++ } + -+ // usage flags did not change -+} ++ if (x == cc0_rtx) ++ { ++ mark_myuse (FIRST_PSEUDO_REGISTER); ++ return; ++ } + - - /* - * 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::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; - } - } ++ RTX_CODE code = GET_CODE(x); + -+ update_insn2index (); - update_insn_infos (); - } - -@@ -1088,11 +1148,11 @@ opt_reg_rename (void) - { - if (JUMP_LABEL(*i) == insn) - { -- std::map::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::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::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 -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); ++ /* 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; ++ } + -+ 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; -+ } ++ // 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; + -+ inline bool -+ has_dst_memreg () const -+ { -+ return dst_mem_reg >= 0; -+ } ++ int code = GET_CODE(SET_SRC(x)); ++ if (code == ASM_OPERANDS) ++ hard |= def | use; ++ return; ++ } + -+ inline bool -+ has_dst_addr () const -+ { -+ return dst_mem_addr != 0; -+ } ++ if (code == TRAP_IF) ++ { ++ /* mark all registers used. */ ++ hard = use = myuse = (1 << FIRST_PSEUDO_REGISTER) - 1; ++ return; ++ } + -+ inline bool -+ is_label () const -+ { -+ return label; -+ } ++ 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; ++ } ++ } + -+ inline bool -+ is_jump () const -+ { -+ return jump; -+ } ++ if (code == POST_INC || code == PRE_DEC || code == CLOBBER) ++ def |= myuse; ++} + -+ inline bool -+ is_call () const -+ { -+ return call; -+ } ++void ++insn_info::fledder_src_mem (rtx src) ++{ ++ src_mem = true; ++ rtx mem = XEXP(src, 0); + -+ inline unsigned -+ get_dst_addr () const -+ { -+ return dst_mem_addr; -+ } ++ 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); + - 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 - } - ++ 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::immediate2base (unsigned regno, unsigned base) ++insn_info::fledder (rtx set) +{ -+ rtx set = PATTERN (get_insn ()); ++ if (!set || GET_CODE(set) == PARALLEL) ++ return; ++ ++ rtx dst = SET_DEST(set); + rtx src = SET_SRC(set); -+ machine_mode mode = GET_MODE(SET_DEST(set)); + -+ unsigned addr = get_dst_addr (); -+ unsigned offset = addr - base; ++ if (dst == cc0_rtx) ++ { ++ compare = true; ++ set = src; ++ dst = SET_DEST(set); ++ src = SET_SRC(set); ++ } + -+ 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)); ++ if (GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG) ++ dst = XEXP(dst, 0); + -+ SET_INSN_DELETED(insn); -+ insn = emit_insn_after (pattern, insn); ++ mode = GET_MODE(dst); ++ if (mode == VOIDmode) ++ mode = GET_MODE(src); + -+ mark_use (regno); ++ if (REG_P(dst)) ++ { ++ dst_reg = dst; ++ } ++ else if (MEM_P(dst)) ++ { ++ dst_mem = true; ++ rtx mem = XEXP(dst, 0); + -+ 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; ++ 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); + -+ for (unsigned i = 0; i < infos.size (); ++i) ++ 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)); ++ } ++ } ++ } ++ } ++ ++ /* 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) + { -+ insn_info & ii = infos[i]; -+ if (!ii.is_dst_mem () || !ii.has_dst_addr () || ii.has_dst_memreg()) -+ continue; ++ 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); ++ } + -+ unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00; -+ if (!freemask) -+ continue; ++ 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; ++} + -+ std::vector 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; ++/* 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; + -+ freemask &= ~(jj.get_use () | jj.get_def ()); -+ if (!freemask) -+ break; ++ x->u.reg.attrs = reg->u.reg.attrs; ++ return x; ++} + -+ 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; ++/* 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; + -+ found.push_back (j); -+ } -+ } ++ RTX_CODE code = GET_CODE(x); + -+ if (freemask && found.size () > 2) ++ const char *fmt = GET_RTX_FORMAT(code); ++ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ++ { ++ if (fmt[i] == 'e') + { -+ unsigned regno = bit2regno (freemask); -+ log ("modifying %d immediate using %s\n", found.size (), reg_names[regno]); -+ -+ for (auto k = found.begin (); k != found.end (); ++k) ++ rtx y = XEXP(x, i); ++ if (REG_P(y)) + { -+ insn_info & kk = infos[*k]; -+ kk.immediate2base (regno, base); ++ if (REGNO(y) == oldregno) ++ return y; ++ } ++ else ++ { ++ rtx r = find_reg_by_no (y, oldregno); ++ if (r) ++ return r; + } -+ -+ // 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; + } -+ -+ i = j; ++ 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; ++ } + } -+ -+ if (change_count) -+ update_insn2index (); -+ -+ return change_count; ++ return 0; +} + - 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 -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; -+ } ++/* ++ * Collect some data. ++ */ ++static std::vector infos; ++typedef std::vector::iterator insn_info_iterator; + - 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 -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; - } ++// insn->u2.insn_uid -> rtx_insn * ++static std::multimap label2jump; ++typedef std::multimap::iterator l2j_iterator; + -+ inline void -+ set_use(unsigned u) -+ { -+ use = u; -+ } ++// index -> index ++static std::multimap jump2label; ++typedef std::multimap::iterator j2l_iterator; + - 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 -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 -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 @@ - - - -@@ -56,12 +57,13 @@ - - - - - -- -@@ -115,6 +118,7 @@ - - - -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 -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; - } - - inline bool - has_dst_addr () const - { -- return dst_mem_addr != 0; -+ return dst_mem_addr; - } - - inline bool -@@ -232,25 +234,55 @@ class insn_info - inline bool - is_src_reg () const - { -- return src_reg; -+ return src_reg && !src_plus; -+ } ++static std::map insn2info; ++typedef std::map::iterator i2i_iterator; + -+ inline bool -+ is_src_plus () const -+ { -+ return src_reg && src_plus; -+ } ++static std::set scan_starts; ++typedef std::set::iterator su_iterator; + -+ 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; -+ } ++static insn_info * info0; ++static unsigned usable_regs; + -+ inline rtx -+ get_dst_reg () const -+ { -+ return dst_reg; -+ } ++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]; ++} + -+ inline int -+ get_src_mem_regno () const -+ { -+ return src_mem_reg ? REGNO(src_mem_reg) : -1; -+ } ++static void ++update_label2jump () ++{ ++ update_insn2index (); + -+ 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; -+ } ++ 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)); ++ } ++} + - inline insn_info & - drop_def () - { -@@ -524,6 +563,10 @@ class insn_info - { - return def & ~hard & ~use & 0x7fff; - } ++int ++insn_info::get_index () const ++{ ++ insn_info * ii = &infos[0]; + -+ void -+ set_insn (rtx_insn * newinsn); ++ if (ii == info0) ++ { ++ ptrdiff_t diff = ((char const *) this - (char const *) ii); ++ unsigned pos = diff / sizeof(insn_info); ++ if (pos < infos.size ()) ++ return pos; ++ } + - }; - - 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) ++// realloc happened... ++ for (unsigned i = 0; i < infos.size (); ++i) ++ if (infos[i].get_insn () == this->insn) ++ return i; ++ ++// whoops!? ++ return 0; ++} ++ ++void ++insn_info::plus_to_move (rtx_insn * newinsn) +{ + insn = newinsn; -+ fledder (PATTERN (insn)); ++ src_op = (rtx_code) 0; ++ src_reg = XEXP(PATTERN (newinsn), 1); ++ insn2info.insert (std::make_pair (insn, this)); ++// usage flags did not change +} + +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 (); - - CC_STATUS_INIT; -- NOTICE_UPDATE_CC(PATTERN (insn1), insn1); -+ NOTICE_UPDATE_CC (PATTERN (insn1), insn1); - if (cc_status.value1 || cc_status.value2) - continue; - -@@ -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; - } - -- /* 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; - -- ii.merge (jj); -+ ii.or_use (jj); - } -- unsigned freemask = ~ii.get_use (); -+ 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; - /* 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; - -+ if (REGNO(reg) == FRAME_POINTER_REGNUM) -+ { -+ // mark as "do not touch" -+ clobbers.push_back (reg); -+ break; -+ } ++insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii) ++{ ++ insn = newinsn; + - 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) - - if (usea5 && a5offset == -4) - { -- for (std::vector::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 (); -- - if (freemask & (1 << FRAME_POINTER_REGNUM)) - { - log ("dropping unused frame pointer\n"); - for (std::vector::iterator i = a5pos.begin (); i != a5pos.end (); ++i) - SET_INSN_DELETED(infos[*i].get_insn ()); ++ std::swap (*this, ii); + -+ /* convert parameter access via a5 into a7. */ -+ for (unsigned i = 0; i < infos.size (); ++i) -+ { -+ insn_info & ii = infos[i]; ++ insn2info.insert (std::make_pair (insn, this)); ++ insn2info.insert (std::make_pair (ii.insn, &ii)); ++ ++// usage flags did not change ++} + -+ if (ii.is_dst_reg () && ii.get_src_mem_regno () == FRAME_POINTER_REGNUM) ++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 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); ++ 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); ++ } ++} + -+ ++changed; - } - } - -- 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) - { - 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 -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 -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 - - rtx dst_reg; - rtx dst_mem_reg; -+ rtx dst_symbol; - rtx src_reg; - rtx src_mem_reg; -+ rtx src_symbol; - unsigned dst_mem_addr; - - 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) - { - } - -@@ -201,6 +205,12 @@ class insn_info - return dst_mem_reg; - } - -+ inline rtx -+ get_dst_symbol () const -+ { -+ return dst_symbol; -+ } ++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); ++} + - 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) ++void ++insn_info::set_insn (rtx_insn * newinsn) ++{ ++ insn = newinsn; ++ ++ reset_flags (); ++ ++ fledder (single_set (insn)); ++} ++ ++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; ++ ++ 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) + { -+ mem = XEXP(mem, 0); -+ if (GET_CODE(mem) == PLUS) ++ 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 (apply) + { -+ rtx sym = XEXP(mem, 0); -+ if (GET_CODE(sym) == SYMBOL_REF) -+ { -+ dst_plus = true; -+ dst_symbol = sym; -+ dst_mem_addr = INTVAL(XEXP(mem, 1)); -+ } ++ dst_mem_reg = reg; ++ dst_mem = true; ++ dst_mem_addr = offset; ++ dst_plus = offset != 0; + } + } - } - - 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) ++ } ++ ++ 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) + { -+ mem = XEXP(mem, 0); -+ if (GET_CODE(mem) == PLUS) ++ 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))); ++ ++ /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */ ++ if (src_op) + { -+ rtx sym = XEXP(mem, 0); -+ if (GET_CODE(sym) == SYMBOL_REF) ++ if (src_ee) ++ src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval)); ++ else + { -+ src_plus = true; -+ src_symbol = sym; -+ src_intval = INTVAL(XEXP(mem, 1)); ++ 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); + } + } ++ ++ if (apply) ++ { ++ src_mem_reg = reg; ++ src_mem = true; ++ src_mem_addr = offset; ++ src_plus = offset != 0; ++ } + } - } - else if (GET_CODE(src) == CONST_INT) - { -@@ -749,7 +791,6 @@ insn_info::fledder (rtx set) - } - } - } -- - } - - /* create a copy for a reg. Optional specify a new register number. */ -@@ -813,6 +854,7 @@ static std::vector jumps; - static std::map insn2index; - - static insn_info * info0; -+static unsigned usable_regs; - - static void - update_insn2index () -@@ -1107,6 +1149,27 @@ update_insn_infos (void) - } - ++pass; - } ++ } ++ ++ 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); ++ ++ mark_myuse (regno); ++ ++ 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 (); ++} ++ ++/* ++ * 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; ++ ++ // not dead if usage is reported in the next statement ++ return !ii.is_use (regno) && !ii.is_hard (regno); ++ } ++ return true; ++} ++ ++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; ++ ++ insn_info & ii = *i->second; ++ ++ 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"); ++ } ++ ++ 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)) ++ { ++ 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, " "); ++ ++ 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, " "); ++ ++ 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, " "); ++ } + -+ /* 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; ++ if (f == stderr) ++ fprintf (f, "\n"); + -+ zz.or_use (ii); ++} ++ ++/* ++ * 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); + -+ /* always allow a0/a1, d0/d1. */ -+ usable_regs = zz.get_use () | 0x303; -+ if (flag_pic) -+ usable_regs &= ~(1 << PIC_REG); ++ rtx_insn * insn = infos[i].get_insn (); ++ if (i < infos.size ()) ++ append_reg_usage (stderr, insn); + -+ if (infos.size () && infos[0].is_use (FRAME_POINTER_REGNUM)) -+ usable_regs &= ~(1 << FRAME_POINTER_REGNUM); ++ fprintf (stderr, "\t"); ++ debug_rtx (insn); + -+ usable_regs &= ~(1 << STACK_POINTER_REGNUM); - } - - /* -@@ -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; - -+ rtx with_symbol = ii.get_dst_symbol (); -+ - std::vector found; - found.push_back (i); - unsigned base = ii.get_dst_addr (); -@@ -2645,22 +2710,35 @@ opt_absolute (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 () && jj.get_dst_symbol () == with_symbol) - { - unsigned addr = jj.get_dst_addr (); - if (addr < base) - base = addr; -- if (addr - base > 0x7ffc) -- continue; - - found.push_back (j); - } - } - -+ if (freemask && found.size () > 2) ++ if (all) + { -+ /* 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; -+ } ++ 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); + } - 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) - { -@@ -2669,7 +2747,19 @@ opt_absolute (void) - } - - // 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 -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; ++/* 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 & todo = scan_starts; + - 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; -+ } ++ if (todo.begin () == todo.end ()) ++ todo.insert (infos.size () - 1); + - 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; - } - -+ inline bool -+ has_src_addr () const -+ { -+ return src_mem_addr; -+ } ++ bool locka4 = flag_pic >= 3; + - inline bool - is_label () const - { -@@ -241,6 +260,12 @@ class insn_info - return dst_mem_addr; - } - -+ inline unsigned -+ get_src_addr () const -+ { -+ return src_mem_addr; -+ } ++ while (!todo.empty ()) ++ { ++ int start = *todo.begin (); ++ todo.erase (todo.begin ()); ++ insn_info ii = infos[start]; + - 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; -+ } ++ enum proepis proepi = ii.in_proepi (); + - 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); ++ // mark sp reg as used. ++ if (proepi >= IN_EPILOGUE) ++ ii.mark_use (STACK_POINTER_REGNUM), infos[start].mark_use (STACK_POINTER_REGNUM); + - 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 - } - -+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') ++ for (int pos = start; pos >= 0; --pos) + { -+ rtx y = XEXP(x, i); -+ if (REG_P(y) && REGNO(y) == regno) ++ insn_info & pp = infos[pos]; ++ rtx_insn * insn = pp.get_insn (); ++ ++ // do not run into previous epilogue ++ if (pp.in_proepi () >= IN_EPILOGUE && !proepi) ++ break; ++ ++ proepi = pp.in_proepi (); ++ ++ /* no new information -> break. */ ++ if (pos != start && pp.is_visited () && !JUMP_P(insn) && pp.contains (ii)) ++ break; ++ ++ ii.clear_hard_def (); ++ ii.merge (pp); ++ ++ if (LABEL_P(insn)) ++ { ++ /* work on all jumps referring to that label. */ ++ l2j_iterator i = label2jump.find (insn->u2.insn_uid); ++ ++ /* 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 (); ++ ++ /* 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; ++ } ++ ++ continue; ++ } ++ ++ pp.mark_visited (); ++ ++ 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)) + { -+ XEXP(x, i) = newreg; -+ if (offset && i + 1 < GET_RTX_LENGTH(code)) ++ if (pos != start && ii.in_proepi ()) + { -+ 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); ++ 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 -+ replace_reg (y, regno, newreg, offset); ++ /* 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); ++ } ++ ++ // 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) ++ use.make_hard (); ++ ++ ii.merge (use); ++ pp.update (ii); ++ ii.updateWith (use); + } -+ 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); -+} ++ /* 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; + - void - insn_info::set_insn (rtx_insn * newinsn) - { -@@ -923,32 +995,63 @@ insn_info::set_insn (rtx_insn * newinsn) - } - - 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); - - 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); ++ zz.or_use (ii); ++ } + -+ 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) -+ { -+ 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))); ++ /* always allow a0/a1, d0/d1. */ ++ usable_regs = zz.get_use () | 0x303; ++ if (flag_pic) ++ usable_regs &= ~(1 << PIC_REG); + -+ if (src_plus && rtx_equal_p (olddst, XEXP(src, 0))) -+ XEXP(src, 0) = dst; ++ if (infos.size () && infos[0].is_use (FRAME_POINTER_REGNUM)) ++ usable_regs &= ~(1 << FRAME_POINTER_REGNUM); + -+ dst_mem_reg = reg; -+ dst_mem = true; -+ dst_mem_addr = offset; -+ dst_plus = offset != 0; -+ } -+ } ++ usable_regs &= ~(1 << STACK_POINTER_REGNUM); ++} + -+ if (is_src_mem () && (has_src_addr () || get_src_symbol ()) && !has_src_memreg () && get_src_symbol () == with_symbol) ++enum AbortCodes ++{ ++ E_OK, E_NO_JUMP_LABEL, E_JUMP_TABLE_MISMATCH, E_JUMP_GOTO_LABEL, E_SP_MISMATCH ++}; ++ ++/* ++ * 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; ++ ++ clear (); ++ ++ enum proepis inproepilogue = IN_PROLOGUE; ++ /* create a vector with relevant insn. */ ++ for (insn = get_insns (); insn; insn = next) + { -+ unsigned addr = get_src_addr (); -+ unsigned offset = addr - base; -+ if (offset <= 0x7ffe) ++ next = NEXT_INSN (insn); ++ ++ if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn)) + { -+ 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; -+ } -+ } ++ infos.push_back (insn_info (insn, inproepilogue)); ++ insn_info & ii = infos[infos.size () - 1]; + -+ 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. -+ */ - if (freemask & (1 << FRAME_POINTER_REGNUM)) - { - log ("dropping unused frame pointer\n"); -- for (std::vector::iterator i = a5pos.begin (); i != a5pos.end (); ++i) -- SET_INSN_DELETED(infos[*i].get_insn ()); -+ for (auto i = a5pos.rbegin (); i != a5pos.rend (); ++i) ++ if (JUMP_P(insn)) + { -+ 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 ()) ++ if (inproepilogue || ANY_RETURN_P(PATTERN (insn))) ++ { ++ if (ANY_RETURN_P(PATTERN (insn))) ++ ii.set_proepi (IN_EPILOGUE); + -+ 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 (); ++ 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; ++ } + -+ 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 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); ++ ii.mark_jump (); ++ if (jump_table) + { -+ if (max - addr <= 0x7ffe) ++ if (XEXP(jump_table, 0) != insn) + { -+ base = addr; -+ found.push_back (j); ++ if (be_very_verbose) ++ { ++ debug_rtx (insn); ++ debug_rtx (jump_table); ++ } ++ result = E_JUMP_TABLE_MISMATCH; ++ jump_table = 0; ++ continue; ++ } ++ ++ // -> 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)) ++ { ++ 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)) ++ { ++ if (insn->jump) ++ { ++ ii.set_proepi (IN_EPILOGUE); ++ ii.mark_jump (); ++ scan_starts.insert (infos.size () - 1); + } -+ else if (addr - base <= 0x7ffe) ++ ii.mark_call (); ++ if (inproepilogue) + { -+ if (addr > max) -+ max = addr; -+ found.push_back (j); -+ continue; ++ scan_starts.insert (infos.size () - 1); ++ inproepilogue = IN_CODE; + } + } -+ if (j_src) ++ else + { -+ unsigned addr = jj.get_src_addr (); -+ if (addr < base) ++ rtx set = single_set (insn); ++ if (set) ++ ii.fledder (set); ++ ++ for (rtx next, note = REG_NOTES(insn); note; note = next) + { -+ if (max - addr <= 0x7ffe) ++ next = XEXP(note, 1); ++ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND) + { -+ base = addr; -+ found.push_back (j); -+ continue; ++ jump_table = XEXP(note, 0); + } + } -+ 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; + -+ /* 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; + } - ++change_count; -+ --i; - } -- -- i = j; - } - - if (change_count) - -From 6e6ca44d77a0ac430aaa9d55181fada079ad76d1 Mon Sep 17 00:00:00 2001 -From: bebbo -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); - -- 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; -+ } - } - } - } - -From bcacd054f6a8b47c7fa16580697a23fc0cd3393b Mon Sep 17 00:00:00 2001 -From: bebbo -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 @@ - - - -+ - - - -@@ -58,6 +59,7 @@ - - - -+ - - - -@@ -106,6 +108,7 @@ - - - -+ - - - -@@ -119,6 +122,7 @@ - - - -+ - - - -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; -+ } ++ } ++ 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 (); + -+ inline machine_mode -+ get_mode () const -+ { -+ return mode; -+ } ++ return result; ++} + - 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; ++/* convert the lowest set bit into a register number. */ ++static int ++bit2regno (unsigned bit) ++{ ++ if (!bit) ++ return -1; + -+ mode = VOIDmode; ++ unsigned regno = 0; ++ while (!(bit & 1)) ++ { ++ ++regno; ++ bit >>= 1; ++ } ++ return regno; ++} + -+ dst_reg = 0; -+ dst_mem_reg = 0; -+ dst_symbol = 0; -+ src_reg = 0; -+ src_mem_reg = 0; -+ src_symbol = 0; -+ dst_mem_addr = 0; ++/* 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 = infos[index]; ++ if (ii.is_myuse (regno) || ii.is_def (regno)) ++ return true; ++ } ++ return false; ++} + -+ src_mem_addr = 0; -+ } ++/* ++ * 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; + - inline bool - is_empty () - { -@@ -711,8 +746,6 @@ insn_info::fledder (rtx set) - rtx dst = SET_DEST(set); - rtx src = SET_SRC(set); - -- mode = GET_MODE(dst); -- - if (dst == cc0_rtx) - { - compare = true; -@@ -721,6 +754,8 @@ insn_info::fledder (rtx set) - src = SET_SRC(set); - } - -+ mode = GET_MODE(dst); ++ /* do not run over RETURNS */ ++ insn_info & jj = infos[start]; + - if (REG_P(dst)) - { - dst_reg = dst; -@@ -991,6 +1026,9 @@ void - insn_info::set_insn (rtx_insn * newinsn) - { - insn = newinsn; ++ /* stop at labels. If a label is a start pos, a search is maybe started again. */ ++ if (jj.is_label ()) ++ break; + -+ reset_flags (); ++ insn_info & bb = infos[startm1]; ++ if (jj.in_proepi () == IN_CODE && bb.in_proepi () >= IN_EPILOGUE) ++ break; + - 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; ++ /* found the definition without use. */ ++ if (jj.is_def (rename_regno) && !jj.is_use (rename_regno)) ++ break; + -+ unsigned lastsub = 0; -+ for (unsigned index = infos.size () - 2; index > 0; --index) - { -- rtx_insn * insn = infos[index].get_insn (); -- rtx seti = single_set (insn); -- if (!seti) -+ insn_info & i1 = infos[index]; ++ start = startm1; ++ } ++ return start; ++} + -+ /* 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) ++/* ++ * 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]; ++ ++ /* do not rename if register is hard or used in same statement. */ ++ const unsigned rename_regbit = ii.get_regbit (); ++ if (!rename_regbit) + 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 todo; -- std::vector 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) ++ ++ const unsigned rename_regno = bit2regno (rename_regbit); ++ ++ /* get the mask for free registers. */ ++ 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 (); ++ ++ /* do not use a4 if compiling baserel */ ++ if (flag_pic >= 3) ++ mask &= ~(1 << PIC_REG); ++ ++ if (!mask) ++ continue; ++ ++ /* first = pos to start, second indicates to treat def as use. */ ++ std::set todo; ++ std::set 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 ()) ++ { ++ unsigned runpos = *todo.begin (); ++ todo.erase (todo.begin ()); ++ ++// printf ("runpos %d \n", runpos); fflush (stdout); ++ for (unsigned pos = runpos; mask && pos < infos.size (); ++pos) + { -+ /* patch previous sub - or even a compare. */ -+ insn_info & pp = infos[lastsub]; ++ /* already searched. */ ++ if (found.find (pos) != found.end ()) ++ break; + -+ 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 ()) ++ rtx_insn * insn = infos[pos].get_insn (); ++ if (LABEL_P(insn)) + { -+ /* 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 ()); ++ 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) ++ { ++ 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; ++ ++ unsigned start = find_start (startat, rename_regno); ++// printf ("label %d <- jump %d : start %d\n", pos, startat, start); fflush (stdout); ++ 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 > 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; ++ ++// 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); ++ } ++ } ++ ++ continue; + } - 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; -+ } - } - #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 -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) - } - - 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; ++ insn_info & jj = infos[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 () - -From 1e4de684a62e18bcb9655cbc1029c24dd426fcb5 Mon Sep 17 00:00:00 2001 -From: bebbo -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 > & loc, rtx x, unsigned oldr - static std::vector infos; - static std::vector jumps; - static std::map insn2index; -+typedef std::vector::iterator insn_info_iterator; -+typedef std::vector::iterator rtx_insn_iterator; -+typedef std::map::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::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::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::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 -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 -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 -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 -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) - { - insn_info & ii = infos[i]; - -+ if (ii.is_compare()) -+ continue; ++ /* marked as hard reg -> invalid rename */ ++ if (jj.get_use () & jj.get_hard () & rename_regbit) ++ { ++ mask = 0; ++ break; ++ } + - 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; ++ /* 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; + - rtx with_symbol = is_dst ? ii.get_dst_symbol () : ii.get_src_symbol (); - - std::vector 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; ++ /* 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; ++ } + - if (j_dst) - { - unsigned addr = jj.get_dst_addr (); - -From 9e1dd52e9e1bdb1ca9af945c5853b9d5b3a9fb46 Mon Sep 17 00:00:00 2001 -From: bebbo -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); - } - -+ if (GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG) -+ dst = XEXP(dst, 0); ++ /* update free regs. */ ++ mask &= ~jj.get_use (); ++ mask &= ~jj.get_def (); ++ if (!mask) ++ break; + - 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(src) == PLUS) -+ /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */ -+ if (*GET_RTX_FORMAT(GET_CODE(src)) == 'e') - { -- 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) ++ found.insert (pos); ++ ++ /* follow jump and/or next insn. */ ++ if (JUMP_P(insn)) + { -+ src_const = true; -+ src_mem_addr = INTVAL(konst); ++ for (j2l_iterator i = jump2label.find (pos), k = i; i != jump2label.end () && i->first == k->first; ++ ++i) ++ { ++ unsigned label_index = i->second; ++ ++ /* 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; + } -+ else if (REG_P(konst)) ++ } ++ } ++ ++ if (mask) ++ { ++ int oldregno = bit2regno (rename_regbit); ++ int newregno = bit2regno (mask); ++ ++ /* check the renamed insns. */ ++ std::vector positions; ++ for (std::set::iterator i = found.begin (); i != found.end (); ++i) ++ { ++ insn_info & rr = infos[*i]; ++ rtx_insn * insn = rr.get_insn (); ++ ++ /* get rename locations. */ ++ rtx from = find_reg_by_no (PATTERN (insn), oldregno); ++ if (from) + { -+ src_reg = konst; /* dst_reg = dst_reg OP src_reg: store src_reg not dst_reg */ ++ rtx to = gen_raw_REG (GET_MODE(from), newregno); ++ validate_replace_rtx_group (from, to, insn); ++ ++ positions.push_back (*i); + } - } - } - } -@@ -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], ++ } ++ ++ 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); - - /* 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) - { - 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) - { - 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 -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 -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 () - { -- static char fxname[512]; - if (current_function_decl == NULL) - strcpy (fxname, ""); - else -@@ -297,6 +297,12 @@ class insn_info - return src_mem && src_plus; - } - -+ inline bool -+ is_dst_mem_plus () const -+ { -+ return dst_mem && dst_plus; -+ } ++ positions.size (), index); + - 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; -+ } ++ if (be_verbose) ++ { ++ for (std::vector::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. ++ * ++ * consider a loop: ++ * ++ * .L1 ++ * ... ++ * move d0, a0 ; (1) ++ * ... ++ * move xy, (a0)+ ++ * ... ++ * move a0, d0 ; (2) ++ * ... ++ * jxx .L1 ++ * ++ * Then the statements (1) and (2) can be moved out of the loop: ++ * ++ * move d0, a0 ; (3) ++ * .L1 ++ * ... ++ * move *, (a0)+ ; a0 is modified somehow ++ * ... ++ * jxx .L1 ++ * move a0, d0 ; (4) ++ * ++ * if all criteria are met: ++ * ++ * a) no other jump to .L1 -> (LABEL_NUSES(insn) == 1) ++ * b) no other use of d0 inside the loop ++ * c) no other use of a0 before (1) ++ * d) no other use of a1 after (2) ++ * ++ * Optional: ++ * - omit (4) if d0 is dead ++ * ++ * this will e.g. convert ++ .L6: ++ move.l d0,a1 ++ move.b (a1)+,d1 ++ move.l a1,d0 ++ move.b d1,(a0)+ ++ cmp.b #0, d1 ++ jne .L6 ++ * to ++ move.l d0,a1 ++ .L6: ++ move.b (a1)+,d1 ++ 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 unsigned ++opt_propagate_moves () ++{ ++ unsigned change_count = 0; ++ rtx_insn * current_label = 0; ++ unsigned current_label_index; ++ std::vector reg_reg; ++ std::vector jump_out; ++ ++ /* start at 1 since there must be an insn before the label. */ ++ for (unsigned index = 1; index < infos.size (); ++index) ++ { ++ 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; ++ } + - inline int - get_src_intval () const - { - return src_mem_addr; - } - -+ inline int -+ get_dst_intval () const -+ { -+ return dst_mem_addr; -+ } ++ if (current_label == 0) ++ continue; + - 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; ++ if (NONJUMP_INSN_P(insn)) ++ { ++ // check for set reg, reg ++ rtx set = single_set (insn); ++ if (set) ++ { ++ rtx src = SET_SRC(set); ++ rtx dst = SET_DEST(set); ++ if (REG_P(src) && REG_P(dst)) ++ reg_reg.push_back (index); ++ } ++ else ++ current_label = 0; + - std::vector regs; - std::vector clobbers; - for (int j = 0; j < XVECLEN(pattern, 0); ++j) -@@ -2607,13 +2631,6 @@ opt_shrink_stack_frame (void) - else - continue; - -- 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)); - } - -- /* 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; - } - } - } ++ continue; ++ } + -+ 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) ++ if (JUMP_P(insn)) ++ { ++ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn); ++ if (label != current_label) + { -+ rtx plus = XEXP(XEXP(pattern, 1), 0); -+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, ii.get_src_intval () - adjust); ++ /* 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; + } - -- 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); - } - } - } -@@ -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 -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) ++ if (reg_reg.size () > 1) ++ { ++ /* Search for reg/reg pairs. */ ++ for (std::vector::iterator i = reg_reg.begin (); i != reg_reg.end () && i + 1 != reg_reg.end (); ++ ) + { -+ mask = 0; -+ break; -+ } ++ bool inc = true; ++ for (std::vector::iterator j = i + 1; j != reg_reg.end ();) ++ { ++ 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 = infos[*j].get_insn (); ++ rtx setj = single_set (jj); ++ rtx srcj = SET_SRC(setj); ++ rtx dstj = SET_DEST(setj); + - /* update free regs. */ - mask &= ~jj.get_use (); - mask &= ~jj.get_def (); - -From b35c1e12d6be7dfaf301801267ff558f6b149be5 Mon Sep 17 00:00:00 2001 -From: bebbo -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)); - } - ++ if (rtx_equal_p (srci, dstj) && rtx_equal_p (srcj, dsti)) ++ { ++ /* Ensure correct usage. */ ++ 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; ++ } + -+int -+amigaos_function_arg_reg(unsigned regno) -+{ -+ return mycum.regs_already_used & (1 << regno) != 0; -+} ++ std::vector fixups; + - /* 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=' 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 - ++ /* 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::iterator label_iter = jump_out.begin (); ++ int fixup = 0; + -+/* 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 ++ 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; ++ } + -+/* The default number of data, address and float registers to use when -+ user specified '-mregparm' switch, not '-mregparm=' option. */ -+#undef AMIGAOS_DEFAULT_REGPARM -+#define AMIGAOS_DEFAULT_REGPARM 2 ++ 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); + -+/* 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) ++ if (reg_overlap_mentioned_p (dsti, dst)) ++ { ++ if (REG_P(dst)) ++ break; ++ if (!MEM_P(dst)) ++ break; + -+extern int -+amigaos_function_arg_reg(unsigned regno); - -From 42f9687b3643a14d216c68b685a8b79f0e860c0e Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 > & loc, rtx x, unsigned oldr - * Collect some data. - */ - static std::vector infos; --static std::vector jumps; --static std::map insn2index; - typedef std::vector::iterator insn_info_iterator; --typedef std::vector::iterator rtx_insn_iterator; ++ 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; ++ } + -+static std::multimap label2jump; -+typedef std::multimap::iterator l2j_iterator; ++ if (reg_overlap_mentioned_p (dsti, src)) ++ { ++ if (REG_P(src)) ++ fixup += 0; ++ else ++ { ++ if (!MEM_P(src)) ++ break; + -+static std::map insn2index; - typedef std::map::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) - { - -- i2i_iterator i = insn2index.find (insn); -+ i2i_iterator i = insn2index.find (insn); - if (i == insn2index.end ()) - return; - -@@ -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 () - { - rtx_insn *insn, *next; ++ 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; ++ } ++ } ++ } ++ } ++ } + -+ rtx jump_table = 0; ++ /* 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); + - clear (); - - char inproepilogue = 1; -@@ -1360,10 +1363,50 @@ update_insns () - - if (JUMP_P(insn)) - { -- jumps.push_back (insn); - inproepilogue = 0; - - ii.mark_jump (); ++ log ("(p) propagate_moves condition met, moving regs %s, %s\n", ++ reg_names[REGNO(srci)], ++ reg_names[REGNO(dsti)]); + -+ 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; -+ } ++ /* Move in front of loop and mark as dead. */ ++ rtx_insn * newii = make_insn_raw (PATTERN (ii)); ++ SET_INSN_DELETED(ii); + -+ // -> 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)); -+ } ++ /* 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_reg_note (newii, REG_DEAD, srci); + -+ jump_table = 0; -+ } -+ else -+ { -+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn); -+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn)); -+ } ++ add_insn_after (newii, before, 0); + - } - else if (LABEL_P(insn)) - { -@@ -1378,6 +1421,16 @@ update_insns () - rtx set = single_set (insn); - if (set) - ii.fledder (set); ++ /* Move behind loop - into next BB. */ ++ rtx_insn * newjj = make_insn_raw (PATTERN (jj)); ++ add_insn_before (newjj, after, 0); ++ SET_INSN_DELETED(jj); + -+ 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); -+ } -+ } ++ reg_reg.erase (j); ++ reg_reg.erase (i); ++ j = reg_reg.end (); ++ inc = false; + - } - } - -@@ -1392,6 +1445,8 @@ update_insns () - - update_insn2index (); - update_insn_infos (); ++ /* 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 ()); + -+ return 0; - } - - /* 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 -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)); ++ 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; ++ } + } - } -- - 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 -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))); - -- 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; - - dst_mem_reg = reg; -@@ -2950,13 +2951,6 @@ opt_absolute (void) - && jj.get_src_symbol () == with_symbol; - - /* 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; - - if (j_dst) - { - -From f89679a40f70cf28bfe2e5b9cec347b292df4d1c Mon Sep 17 00:00:00 2001 -From: bebbo -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) - } - } - -+ /* 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; ++ if (inc) ++ ++j; ++ } ++ if (inc) ++ ++i; ++ } ++ } ++ current_label = 0; + } -+ src = XEXP(src, 0); + } ++ return change_count; ++} + - 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 -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; -+ } ++/** ++ * Search for ++ * ++ * mov x,reg ++ * mov reg,x ++ * cmp #0, reg ++ * jxx ++ * ++ * patterns. ++ * ++ * Use a simple state machine to find the patterns. ++ */ ++static unsigned ++opt_strcpy () ++{ ++ unsigned change_count = 0; ++#if HAVE_cc0 ++ rtx_insn * x2reg = 0; ++ rtx_insn * reg2x; ++ unsigned int regno; + - 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; - -+ src_intval = 0; - src_mem_addr = 0; - } - -@@ -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))); - -- /* 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; -- - 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); -+ } ++ for (unsigned index = 0; index < infos.size (); ++index) ++ { ++ rtx_insn * insn = infos[index].get_insn (); ++ ++ if (!NONJUMP_INSN_P(insn)) ++ { ++ x2reg = 0; ++ continue; ++ } + - 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; - -+ if (ii.get_src_op () && ii.is_src_ee () && !ii.get_src_intval ()) -+ continue; ++ rtx set = single_set (insn); ++ if (!set) ++ { ++ x2reg = 0; ++ 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 (); - -@@ -2917,15 +2935,6 @@ opt_absolute (void) - if (!freemask) - continue; - -- /* 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 (); - - std::vector found; -@@ -2946,6 +2955,9 @@ opt_absolute (void) - if (jj.get_mode () == VOIDmode || jj.is_compare ()) - continue; - -+ if (jj.get_src_op () && jj.is_src_ee () && !jj.get_src_intval ()) -+ continue; ++ if (x2reg && reg2x) ++ { ++ rtx src = SET_SRC(set); ++ if (GET_CODE(src) == COMPARE) ++ { ++ rtx dst = XEXP(src, 0); ++ src = XEXP(src, 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 -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 (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 (src_op == SIGN_EXTEND) ++ /* now check via NOTICE_UPDATE_CC*/ ++ NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x); ++ if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2)) + { -+ 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 (jj.get_mode () == VOIDmode || jj.is_compare ()) - continue; - -From 90e72be90df0d966c935ae3c91476af65f18cb81 Mon Sep 17 00:00:00 2001 -From: bebbo -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; - -@@ -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); - } - -+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 () - { - 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) ++ rtx pattern = gen_rtx_SET(SET_DEST(single_set (reg2x)), SET_SRC(single_set (x2reg))); ++ rtx_insn * newinsn = make_insn_raw (pattern); + -+ // -> 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) ++ if (!insn_invalid_p (newinsn, 0)) + { -+ 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)); -+ } ++ 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); ++ ++ insn = emit_insn_after (pattern, reg2x); ++ insn_invalid_p (insn, 0); ++ ++ ++change_count; + } - } - 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 ++ } ++ x2reg = 0; ++ continue; ++ } ++ reg2x = 0; ++ } + -+ 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; - } ++ /* 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)); ++ } ++ } ++ } ++#endif ++ return change_count; ++} + -+rtx -+amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED) ++/* ++ * convert ++ * ++ * set reg1, plus (reg2, const) ++ * set mem(reg2), y ++ * ++ * -> ++ * set reg1, reg2 ++ * set mem(reg1+), y ++ * ++ * if size of postinc == const ++ * ++ (insn 33 32 35 4 (set (reg/v/f:SI 8 a0 [orig:47 s ] [47]) ++ (plus:SI (reg/v/f:SI 9 a1 [orig:46 s ] [46]) ++ (const_int 1 [0x1]))) sn.c:5 141 {*addsi3_internal} ++ (nil)) ++ (insn 36 35 37 4 (set (mem:QI (reg/v/f:SI 9 a1 [orig:46 s ] [46]) [0 MEM[base: s_17, offset: 4294967295B]+0 S1 A8]) ++ (mem:QI (post_inc:SI (reg/v/f:SI 10 a2 [orig:53 s2 ] [53])) [0 MEM[base: s2_19, offset: 4294967295B]+0 S1 A8])) sn.c:5 46 {*m68k.md:1083} ++ (expr_list:REG_INC (reg/v/f:SI 10 a2 [orig:53 s2 ] [53]) ++ (nil))) ++ */ ++static unsigned ++opt_commute_add_move (void) +{ -+ if (fntype && aggregate_value_p (TREE_TYPE(fntype), fntype)) -+ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM); ++ unsigned change_count = 0; + -+ return 0; ++ 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 ()) ++ 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 ()) ++ continue; ++ ++ rtx_insn * insn = ii.get_insn (); ++ ++ rtx_insn * next = jj.get_insn (); ++ rtx set2 = single_set (next); ++ rtx dst = SET_DEST(set2); ++ if (!MEM_P(dst)) ++ continue; ++ ++ 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 ())); ++ ++ 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 (newinsn, next); ++ ++ add_reg_note (next, REG_INC, ii.get_dst_reg ()); ++ ++ ++change_count; ++ } ++ else ++ cancel_changes (0); ++ } ++ return change_count; +} + -+rtx -+amigaos_static_chain_rtx (const_tree fntype, bool incoming ATTRIBUTE_UNUSED) ++/* ++ * Replace ++ * ++ * move x,dx ++ * cmp dx,dy ++ * ++ * if dx and dy are both dead after compare. ++ * ++ * with ++ * ++ * sub #n,dx ++ * ++ d0 d1 d2 a0 a1 a7 (insn 99 59 41 7 (set (reg:SI 2 d2) ++ (const_int 1 [0x1])) sn.c:8 38 {*movsi_m68k} ++ (nil)) ++ d0 d1 d2 a0 a1 a7 (insn 41 99 42 7 (set (cc0) ++ (compare (reg/v:SI 1 d1 [orig:54 n ] [54]) ++ (reg:SI 2 d2))) sn.c:8 16 {*m68k.md:499} ++ (expr_list:REG_DEAD (reg:SI 2 d2) ++ (expr_list:REG_DEAD (reg/v:SI 1 d1 [orig:54 n ] [54]) ++ (nil)))) ++ * ++ */ ++static unsigned ++opt_const_cmp_to_sub (void) +{ -+ if (fntype && DECL_STATIC_CHAIN(fntype)) -+ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM); ++ unsigned change_count = 0; ++#if HAVE_cc0 ++ if (infos.size () < 2) ++ return change_count; + -+ return 0; -+} ++ unsigned lastsub = 0; ++ for (unsigned index = infos.size () - 2; index > 0; --index) ++ { ++ insn_info & i1 = infos[index]; + -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); ++ /* we wan't a compare or tst insn, */ ++ if (!i1.is_compare ()) ++ continue; + -+#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 -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)) ++ if (GET_MODE_SIZE(i1.get_mode()) > 4 || !i1.is_dst_reg () || REGNO(i1.get_dst_reg()) > 7) ++ continue; + -+// 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 -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; ++ /* 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; + -+ tree fntype = TREE_TYPE(decl); ++ /* 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 (); + -+ unsigned used = 0; ++ // but still check for usage after this jump ++ j2l_iterator l = jump2label.find (index + 2); ++ if (l == jump2label.end ()) ++ 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)))) ++ 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; + -+ unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low; -+ used |= 1 << regno; -+ } ++ 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 (!(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 -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; ++ if (GET_MODE_SIZE(i0.get_mode()) > 4) ++ continue; ++ ++ if (!i0.is_dst_reg () || !i0.is_src_const () || i0.get_src_op ()) ++ continue; ++ ++ if (i0.get_dst_regno () != i1.get_src_regno ()) ++ continue; ++ ++ 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; ++ ++ rtx jmppattern = single_set (i2.get_insn ()); ++ if (!jmppattern) ++ continue; ++ ++ rtx jmpsrc = XEXP(jmppattern, 1); ++ if (GET_CODE(jmpsrc) != IF_THEN_ELSE) ++ continue; ++ ++ rtx condition = XEXP(jmpsrc, 0); ++ RTX_CODE code = GET_CODE(condition); ++ if (code != EQ && code != NE) ++ continue; ++ ++ 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)); ++ ++ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub)); ++ ++ if (insn_invalid_p (subinsn, 0)) ++ continue; ++ ++ /* 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() */ ++ ++ /* convert cmp/tst into sub */ ++ subinsn = emit_insn_before (PATTERN (subinsn), i1.get_insn ()); ++ i1.set_insn (subinsn); + - 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; -+ } ++ rtx neu = gen_rtx_SET(cc0_rtx, ++ gen_rtx_COMPARE (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), 0))); + -+ inline void -+ mark_visited () -+ { -+ visited = true; -+ } ++ emit_insn_before (neu, i2.get_insn ()); + - void - scan (); - -@@ -959,6 +938,9 @@ typedef std::multimap::iterator l2j_iterator; - static std::map insn2index; - typedef std::map::iterator i2i_iterator; - -+static std::set returns; -+typedef std::set::iterator su_iterator; ++ 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 ()]); + - 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 > 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 (index + 3 == lastsub) ++ { ++ /* patch previous sub - or even a compare. */ ++ insn_info & pp = infos[lastsub]; + -+ if (todo.begin () == todo.end ()) -+ todo.push_back (std::make_pair (infos.size () - 1, insn_info ())); - -- int pass = 0; - while (!todo.empty ()) - { - std::pair 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 (); ++ int diff = lastsubval - intval; ++ rtx c = gen_rtx_CONST_INT (i1.get_mode (), diff); + - 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))) ++ if (pp.is_compare ()) + { -+ returns.insert (infos.size () - 1); -+ inproepilogue = 0; -+ if (ANY_RETURN_P(PATTERN (insn))) -+ continue; ++ /* 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 ()); + } - - ii.mark_jump (); - if (jump_table) - -From b1334e77f8e493eaeb362392f035711d06484be7 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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; ++ else ++ { ++ /* modify the sub. */ ++ XEXP(SET_SRC(PATTERN(pp.get_insn())), 1) = c; ++ } ++ } + -+ int dst_autoinc; -+ int src_autoinc; ++ lastsub = index; ++ ++change_count; ++ } ++ } ++#endif ++ return change_count; ++} + - 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; ++/* ++ * rare and only little gain - but :-) ++ lea (-1,a0),a1 ++ add.l d1,a1 ++ subq.l #1,d1 ++ -> ++ move.l a0,a1 ++ subq.l #1,d1 ++ add.l d1,a1 ++ */ ++static unsigned ++opt_merge_add (void) ++{ ++ unsigned change_count = 0; ++ for (unsigned index = 0; index + 2 < infos.size (); ++index) ++ { ++ insn_info & ii0 = infos[index]; ++ insn_info & ii1 = infos[index + 1]; ++ insn_info & ii2 = infos[index + 2]; + -+ dst_autoinc = 0; -+ src_autoinc = 0; -+ } ++ if (!ii2.is_dst_reg ()) ++ { ++ index += 2; ++ continue; ++ } + -+ inline int -+ get_src_autoinc () const -+ { -+ return src_autoinc; -+ } ++ if (!ii1.is_dst_reg ()) ++ { ++ ++index; ++ continue; ++ } + -+ 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; -+ } ++ if (!ii0.is_dst_reg () || ii0.get_src_op () != PLUS || ii1.get_src_op () != PLUS || ii2.get_src_op () != PLUS) ++ continue; + -+ inline void -+ set_sp_offset (int sp) -+ { -+ sp_offset = sp; -+ } ++ if (!ii0.is_src_const () || !ii2.is_src_const () || ii0.get_src_intval () != ii2.get_src_intval ()) ++ continue; + - inline bool -- visit () const -+ is_visited () const - { - return visited; - } -@@ -607,6 +641,12 @@ class insn_info - visited = true; - } - -+ inline void -+ clear_visited () -+ { -+ visited = false; -+ } ++ if (ii0.get_dst_regno () != ii1.get_dst_regno () || ii1.get_src_regno () != ii2.get_dst_regno ()) ++ continue; + - void - scan (); - -@@ -770,6 +810,12 @@ insn_info::fledder (rtx set) - { - dst_mem = true; - rtx mem = XEXP(dst, 0); ++ rtx_insn * insn1 = ii1.get_insn (); + -+ 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); ++ CC_STATUS_INIT; ++ NOTICE_UPDATE_CC(PATTERN (insn1), insn1); ++ if (cc_status.value1 || cc_status.value2) ++ continue; + - 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); ++ log ("(m) %d: merge_add applied\n", index); + -+ 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 > & loc, rtx x, unsigned oldr - static std::vector infos; - typedef std::vector::iterator insn_info_iterator; - -+// insn->u2.insn_uid -> rtx_insn * - static std::multimap label2jump; - typedef std::multimap::iterator l2j_iterator; - --static std::map insn2index; -+// index -> index -+static std::multimap jump2label; -+typedef std::multimap::iterator j2l_iterator; ++ rtx_insn * insn0 = ii0.get_insn (); ++ rtx set = PATTERN (insn0); + -+static std::map insn2info; - typedef std::map::iterator i2i_iterator; - - static std::set 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)); ++ // 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); + -+ 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)); ++ 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); ++ ++ ++change_count; + } ++ return change_count; +} + - 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 ++// 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; + } + -+ // add entry point -+ std::vector todo; -+ todo.push_back (0); ++// add entry point ++ std::set 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 (); + + for (unsigned index = startpos; index < infos.size (); ++index) + { + insn_info & ii = infos[index]; -+ if (ii.in_proepi ()) -+ continue; ++ if (ii.in_proepi () != IN_CODE) ++ { ++ ii.set_sp_offset (sp_offset); ++ continue; ++ } + + // already visited? sp_offset must match + if (ii.is_visited ()) @@ -28315,7 +4082,7 @@ index a06f1577fb94..43bcf138fc20 100755 + return E_SP_MISMATCH; + + ll.set_sp_offset (sp_offset); -+ todo.push_back (i->second); ++ todo.insert (i->second); + } + continue; + } @@ -28324,7 +4091,7 @@ index a06f1577fb94..43bcf138fc20 100755 + 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 (); @@ -28344,1759 +4111,577 @@ index a06f1577fb94..43bcf138fc20 100755 + return 0; +} + - /** - * 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; - ++/* 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 ++ * 3. adjust stack frame + insns referring to stack pointer ++ * typical code: ++ subq.l #4,sp ++ movem.l #16190,-(sp) ++ move.l 52(sp),d2 ++ move.l 56(sp),d3 ++ ++ * or ++ link a5,#4 ++ movem.l #16190,-(sp) ++ move.l 8(a5),d2 ++ move.l 12(a5),d3 ++ * ++ * => with a5 check only prolog/epilog ++ * => without a5 adjust insns referring sp if offset > startoffset + current sp diff ++ * ++ * startvalue count(pushes)*4 ++ * newstartvalue = startvalue - omitted pushes ++ */ ++static unsigned ++opt_shrink_stack_frame (void) ++{ ++ /* nothing to do. */ ++ if (!infos.size ()) ++ return 0; ++ + /* needed to track sp correctly. */ + update_label2jump (); + if (track_sp ()) + return 0; // do nothing on stack errors + - std::vector 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); ++ std::vector a5pos; ++ ++ unsigned pos = 0; ++ rtx_insn * insn = infos[pos].get_insn (); ++ if (JUMP_P(insn)) /* return -> empty function*/ ++ return 0; ++ ++ bool usea5 = false; ++ int paramstart = 4; ++ int a5offset = 0; ++ ++ /* ++ * Move prologue to temp. ++ * Only register push and parallel insn unless its a link a5 are moved. ++ */ ++ for (; pos < infos.size ();) ++ { ++ insn_info & ii = infos[pos]; ++ insn = ii.get_insn (); ++ ++ if (ii.in_proepi () != IN_PROLOGUE) ++ break; ++ ++ rtx pattern = PATTERN (insn); ++ if (GET_CODE(pattern) == PARALLEL) ++ { ++ 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) ++ { ++ 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; ++ } ++ ++ /* move only the push statements. */ ++ rtx src = SET_SRC(pattern); ++ rtx dest = SET_DEST(pattern); ++ if (REG_P(src)) ++ { ++ if (MEM_P(dest)) ++ { ++ rtx predec = XEXP(dest, 0); ++ if (GET_CODE(predec) == PRE_DEC) ++ { ++ rtx reg = XEXP(predec, 0); ++ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM) ++ { ++ ii.mark_stack (); ++ } ++ } ++ } ++ } ++ 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) == STACK_POINTER_REGNUM && CONST_INT_P(cx)) ++ paramstart -= INTVAL(cx); ++ } ++ ++ if (++pos >= infos.size ()) ++ { ++ return 0; ++ } ++ } ++ ++ if (pos == 0) ++ return 0; ++ ++ unsigned prologueend = pos; ++ ++ /* search epilogues - there can be multiple epilogues. */ ++ while (pos < infos.size ()) ++ { ++ while (pos < infos.size ()) ++ { ++ if (infos[pos].in_proepi () != IN_CODE) ++ break; ++ ++pos; ++ } ++ ++ /* move epilogues away. */ ++ for (; pos < infos.size (); ++pos) ++ { ++ insn_info & ii = infos[pos]; ++ insn = ii.get_insn (); ++ if (JUMP_P(insn) || LABEL_P(insn) || ii.in_proepi () == IN_CODE) ++ break; ++ ++ /* omit the frame pointer a5. */ ++ rtx pattern = PATTERN (insn); ++ if (GET_CODE(pattern) == PARALLEL) ++ { ++ 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) ++ { ++ a5pos.push_back (pos); ++ break; ++ } ++ + } -+ - 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::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; -+ -+ insn_info & ii = infos[index]; -+ if (!ii.in_proepi ()) ++ else if (GET_CODE(pattern) == SET) ++ { ++ /* check for move (a7+), x */ ++ rtx src = SET_SRC(pattern); ++ rtx dst = SET_DEST(pattern); ++ if (REG_P(dst)) + { -+ if (ii.get_sp_offset () != 0) ++ if (MEM_P(src)) + { -+ 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 ()); ++ rtx postinc = XEXP(src, 0); ++ if (GET_CODE(postinc) == POST_INC) ++ { ++ rtx reg = XEXP(postinc, 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 (); ++ } + } + } - } - - /* 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 -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 -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 -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; -+ - 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 -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 -+}; -+ - /* 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; -+ } ++ } ++ } ++ ++pos; ++ } ++ /* gather usage stats without prologue/epilogue */ ++ insn_info ii; ++ for (unsigned i = 0; i < infos.size (); ++i) ++ { ++ insn_info & jj = infos[i]; ++ if (jj.in_proepi () != IN_CODE) ++ continue; + - 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; ++ ii.or_use (jj); ++ } ++ unsigned freemask = ~ii.get_use () & 0x7fff; + - 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|"); ++ rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM); ++ rtx a5 = gen_raw_REG (SImode, FRAME_POINTER_REGNUM); + -+ 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 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; - ++ /* now all push/pop insns are in temp. */ ++ for (unsigned i = 0; i < infos.size (); ++i) ++ { ++ 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 regs; - std::vector 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); -+ -+ ++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 ()) ++ std::vector regs; ++ std::vector clobbers; ++ for (int j = 0; j < XVECLEN(pattern, 0); ++j) ++ { ++ rtx set = XVECEXP(pattern, 0, j); ++ if (GET_CODE(set) == CLOBBER) + { -+ rtx src = XEXP(pattern, 1); -+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), ii.get_src_intval () - adjust); ++ clobbers.push_back (set); ++ continue; + } - } -- -- 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) -+ -+ // 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); ++ rtx dst = SET_DEST(set); ++ rtx src = SET_SRC(set); ++ rtx reg; ++ if (MEM_P(src)) ++ reg = dst; ++ else if (MEM_P(dst)) ++ reg = src; ++ else ++ continue; + -+ 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; -+ } ++ if (i < prologueend) ++ paramstart += 4; ++ unsigned regbit = 1 << REGNO(reg); + -+ 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 ())); -+ } ++ ++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 += GET_MODE_SIZE(GET_MODE(reg)); + } - - ii.unset (FRAME_POINTER_REGNUM); - } - -From 0c94ad510c11dbd020d66482ac4ef28857f86d2e Mon Sep 17 00:00:00 2001 -From: bebbo -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; -+ } ++ else ++ { ++ regs_total_size += GET_MODE_SIZE(GET_MODE(reg)); ++ regs.push_back (copy_reg (reg, -1)); ++ } ++ } + - 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 > todo; -+ std::set 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 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)); ++ /* 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) + { -+ unsigned index = j->second->get_index (); -+ insn_info & jj = infos[index]; -+ if (!jj.is_visited () || !jj.contains (ii)) ++ rtx reg = regs[k]; ++ if (i < prologueend) ++ { ++ /* push */ ++ 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 + { -+ jj.updateWith (ii); -+ todo.insert (index); ++ /* pop */ ++ 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); + } + } - } -+ -+ 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::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 -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 @@ - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - -+ -+ -+ build-gcc -+ 2 -+ D:/develop/workspaces/c1/amigaos-cross-toolchain/.build-m68k/build/gcc-6 -+ -+ - -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 @@ - - - -- -+ - - - -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 -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 -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 -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 -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); -+#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); -+#else -+ asm_fprintf (file, "%I$%lx%08lx%08lx", l[0] & 0xFFFFFFFF, -+ l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF); -+#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); -+#else -+ asm_fprintf (file, "%I$%lx%08lx", l[0] & 0xFFFFFFFF, l[1] & 0xFFFFFFFF); -+#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" ++ } ++ else ++ { ++ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1 + clobbers.size ())); ++ rtx plus; + -+#undef ASM_STABN_OP -+#define ASM_STABN_OP "|\t.stabn\t" -+#endif ++ int x = 0; ++ for (unsigned k = 0; k < regs.size (); ++k) ++ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4; + - #undef PIC_REG - #define PIC_REG 12 - -@@ -410,11 +421,16 @@ if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \ - ")" - - #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)}" -+#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}" - -+#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)}" -+#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. */ - -+#ifdef TARGET_AMIGAOS_VASM - #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 %{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}} " \ -+ "%{mcpu=68020:-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}" -+#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}" -+#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. */ - -+#ifdef TARGET_AMIGAOS_VASM -+#define LINK_COMMAND_SPEC \ -+ "%{!fsyntax-only:" \ -+ "%{!c:" \ -+ "%{!M:" \ -+ "%{!MM:" \ -+ "%{!E:" \ -+ "%{!S:" \ -+ "%(linker) -Cvbcc %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*} }}}}}} " -+#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*} }}}}}} " \ -+ "%{T*} }}}}}} " -+#endif - - extern const char * amiga_m68k_prefix_func(int, const char **); - - -From f86473acc971c74d399d0b0f7de418ab45a9cd46 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 -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 todo; -- todo.push_back (0); -+ std::set 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 -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 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; ++ } + -+ 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); ++ if (i >= prologueend) ++ x = usea5 ? -x : 0; + -+ /* 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; -+ } ++ 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 -= 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, l) = set; ++ } ++ else ++ { ++ /* pop */ ++ 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; ++ } ++ } ++ } + - 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 todo; -+ std::set todo; - std::set 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 -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 -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 -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 -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; ++ 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); + } - } - else - { - -From c11163ef6d4388e710fde92c1cc609ac06b0a5fc Mon Sep 17 00:00:00 2001 -From: bebbo -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; ++ SET_INSN_DELETED(insn); ++ changed = 1; ++ } + } -+ } - replace_reg (PATTERN (insn), FRAME_POINTER_REGNUM, a7, -4); - } - - -From 1ebf051b5bd078fc19f105904090ffc1743752fc Mon Sep 17 00:00:00 2001 -From: bebbo -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; -+ } -+ - 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::iterator j2l_iterator; - static std::map insn2info; - typedef std::map::iterator i2i_iterator; - --static std::set returns; -+static std::set scan_starts; - typedef std::set::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 todo; -- for (su_iterator i = returns.begin (); i != returns.end (); ++i) -- todo.insert (*i); -+ std::set & 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 & 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 (); ++ else ++ { ++ rtx set = PATTERN (insn); + - for (std::vector::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 -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; ++ if (i < prologueend) ++ { ++ /* move x,-(a7). */ ++ rtx src = SET_SRC(set); ++ paramstart += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4; ++ unsigned regbit = 1 << REGNO(src); ++ if (freemask & regbit) ++ { ++ 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 ++ { ++ /* move (a7)+,x */ ++ rtx dst = SET_DEST(set); ++ unsigned regbit = 1 << REGNO(dst); ++ if (freemask & regbit) ++ { ++ log ("(f) remove pop for %s\n", reg_names[REGNO(dst)]); ++ SET_INSN_DELETED(insn); ++ ++changed; ++ } ++ } ++ } ++ } + - 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); ++ /* fix sp offsets. */ ++ if (!usea5 && adjust) ++ { ++ for (unsigned index = 0; index < infos.size (); ++index) ++ { ++ insn_info & ii = infos[index]; ++ if (ii.in_proepi () != IN_CODE) ++ continue; + -+ bool -+ merge_values (rtx * v); ++ rtx pattern = single_set (ii.get_insn ()); ++ if (pattern) ++ patch_sp (pattern, adjust, ii.get_sp_offset ()); ++ } ++ } + -+ bool -+ equal_values (rtx * v) const; ++ 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::reverse_iterator i = a5pos.rbegin (); i != a5pos.rend (); ++i) ++ { ++ int index = *i; ++ SET_INSN_DELETED(infos[index].get_insn ()); + -+ rtx -+ get_value_for (unsigned regno) const; ++ // move to last insn in epilogue ++ while (index - 1 > 0 && infos[index - 1].in_proepi () >= IN_EPILOGUE) ++ --index; + - 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)); -+} ++ 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 ()); ++ } ++ } + -+static const rtx INVALID = (rtx) -1; ++ /* 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 (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); + -+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; -+} ++ 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; ++ } + -+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; -+} ++ 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 ())); ++ } ++ } + -+rtx -+insn_info::get_value_for (unsigned regno) const -+{ -+ if (!values || regno > 15) -+ return 0; -+ return values[regno]; -+} ++ ii.unset (FRAME_POINTER_REGNUM); ++ } + - 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 (); ++ update_insn2index (); ++ ++changed; ++ } ++ } + - 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; ++ return changed; ++} + -+ // do not run into previous epilogue -+ if (pp.in_proepi () >= IN_EPILOGUE && !proepi) -+ break; ++/* 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 ++ * ++ */ + -+ 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 & 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 ++// reset visited flags + for (unsigned index = 0; index < infos.size (); ++index) + { + insn_info & ii = infos[index]; @@ -30104,64 +4689,104 @@ index 26ca56bbb84d..9014295f8b43 100755 + ii.set_sp_offset (0); + } + -+ // add entry point -+ std::set todo; -+ todo.insert (0); ++ update_label2jump (); ++ ++// add entry point ++ std::multimap todo; ++ todo.insert (std::make_pair (0, new track_var ())); + + 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 ()); + -+ 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)) ++ if (index != startpos && ii.is_visited () && ii.get_track_var ()->no_merge_needed (track)) + break; + -+ // mark current insn_info and set sp_offset -+ ii.mark_visited (); ++ // only keep common values at labels ++ if (ii.is_label ()) ++ { ++ if (ii.is_visited ()) ++ { ++ ii.get_track_var ()->merge (track, index); ++ } ++ else ++ { ++ ii.get_track_var ()->assign (track); ++ ii.mark_visited (); ++ } ++ continue; ++ } ++ ++ // mark current insn_info and set sp_offset ++ ii.mark_visited (); ++ ii.get_track_var ()->assign (track); ++ ++ if (ii.is_compare ()) ++ continue; ++ ++ unsigned def = ii.get_def () & 0xffffff; ++ 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 ()) ++ { ++ track->clear_aftercall (index); ++ continue; ++ } + -+ ii.merge_values (values); ++ 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 (i->second); -+ insn_info & jj = infos[i->second]; -+ if (jj.merge_values (values)) -+ ii.clear_visited (); -+ } -+ continue; ++ 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; + } + -+ // track register values for now -+ int regno = ii.get_dst_regno (); -+ if (regno < 0) ++ if (!set || !ii.get_def ()) ++ continue; ++ ++ if (dregno < 0) + { -+ // TODO: track if dst_mem is volatile ++ track->invalidate_mem (SET_DEST(set)); + continue; + } + -+ rtx set = single_set (ii.get_insn ()); -+ if (!set) ++ // 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; + -+ // TODO: check for volatile sources -+ values[regno] = src; -+ -+ for (int i = regno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i) -+ values[regno] = INVALID; ++ track->set (ii.get_mode (), dregno, src, index); + } ++ delete track; + } + return 0; +} @@ -30171,7 +4796,7 @@ index 26ca56bbb84d..9014295f8b43 100755 + * delete those insns. + */ +static unsigned -+opt_elim_dead_assign (void) ++opt_elim_dead_assign (int blocked_regno) +{ + track_regs (); + @@ -30179,11299 +4804,5509 @@ index 26ca56bbb84d..9014295f8b43 100755 + for (int index = infos.size () - 1; index >= 0; --index) + { + insn_info & ii = infos[index]; -+ if (!ii.get_dst_reg ()) ++ 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; -+ } -+ -+ 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))) ++ 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 redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]); ++ log ("(e) %d: eliminate dead assign to %s\n", index, reg_names[ii.get_dst_regno ()]); + SET_INSN_DELETED(insn); + ++change_count; + continue; -+ + } -+ } -+ return change_count; -+} -+ - /* - * Convert a series of move into absolute address into register based moves. - */ - -From 98fb7816dc4ef9e568a068343dbcf331ccdca4d0 Mon Sep 17 00:00:00 2001 -From: bebbo -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; - } - -+ 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); - -+ void -+ fledder_src_mem (rtx src); -+ - /* update usage. */ - void - update (insn_info & o) -@@ -872,6 +882,51 @@ insn_info::scan_rtx (rtx x) - } - } - -+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) ++ // 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 ())) + { -+ rtx sym = XEXP(mem, 0); -+ if (GET_CODE(sym) == SYMBOL_REF) ++ track_var * track = ii.get_track_var (); ++ ++ rtx src = SET_SRC(set); ++ if (track->equals (ii.get_dst_regno (), src)) + { -+ src_plus = true; -+ src_symbol = sym; -+ src_mem_addr = INTVAL(XEXP(mem, 1)); ++ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]); ++ SET_INSN_DELETED(insn); ++ ++change_count; ++ continue; + } -+ } -+ } -+} + - /* 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; ++ if (ii.get_src_reg () && track->equals (ii.get_src_regno (), SET_DEST(set))) + { -+ alt_src_reg = operand; ++ log ("(e) %d: eliminate redundant reverse load to %s\n", index, reg_names[ii.get_dst_regno ()]); ++ SET_INSN_DELETED(insn); ++ ++change_count; ++ continue; + } -+ else if (MEM_P(operand)) ++ ++ // is there a register holding that value? ++ if (!ii.get_src_reg ()) + { -+ // 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); ++ int aliasRegno = track->find_alias (src); ++ if (aliasRegno >= 0 && aliasRegno != ii.get_dst_regno ()) + { -+ 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); - } - -@@ -3333,7 +3361,7 @@ track_regs () - // TODO: check for volatile sources - values[regno] = src; - -- 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 -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 -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; - } - --/* 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 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) - { -- 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; - } - -From 5a66c60ad7bba806de2640310c4e3e4941245aa2 Mon Sep 17 00:00:00 2001 -From: bebbo -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) - { - 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)); - } - - 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 - { - 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; -+ } - } - } - -@@ -2775,6 +2798,33 @@ track_sp () - return 0; - } - -+/* 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; ++ 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; ++ } ++ } + } + } -+ 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); -+ } ++ return change_count; +} + - /** - * 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; - } - -+/* Update the insn_infos to 'know' the value for each register. */ ++/* ++ * Convert a series of move into absolute address into register based moves. ++ */ +static unsigned -+track_regs () ++opt_absolute (void) +{ -+ // reset visited flags -+ for (unsigned index = 0; index < infos.size (); ++index) ++ unsigned change_count = 0; ++ ++ for (unsigned i = 0; i < infos.size (); ++i) + { -+ insn_info & ii = infos[index]; -+ ii.clear_visited (); -+ ii.set_sp_offset (0); -+ } ++ insn_info & ii = infos[i]; + -+ rtx * values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx)); // track register values ++ if (ii.is_compare ()) ++ continue; + -+ // add entry point -+ std::set todo; -+ todo.insert (0); ++ if (ii.get_src_op () && ii.is_src_ee () && !ii.get_src_intval ()) ++ continue; + -+ while (todo.begin () != todo.end ()) -+ { -+ unsigned startpos = *todo.begin (); -+ todo.erase (todo.begin ()); ++ 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 (); + -+ memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx)); ++ if (!is_dst && !is_src) ++ continue; + -+ // track register aliases: know which register refers to this slot -+ // if a register changes, invalidate each referrer -+ std::multimap 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)); ++ if (ii.get_mode () == VOIDmode) ++ continue; + -+ for (unsigned index = startpos; index < infos.size (); ++index) ++ 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 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 & ii = infos[index]; ++ 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; + -+ // already visited? -+ if (ii.is_visited () && ii.equal_values (values)) ++ unsigned tempmask = freemask & ~(jj.get_use () | jj.get_def ()); ++ if (!tempmask) + break; ++ freemask = tempmask; + -+ // mark current insn_info and set sp_offset -+ ii.mark_visited (); ++ if (jj.get_mode () == VOIDmode || jj.is_compare ()) ++ continue; + -+ // do not optimize over labels -+ if (ii.is_label ()) -+ { -+ memset (values, 0xff, FIRST_PSEUDO_REGISTER * sizeof(rtx)); -+ continue; -+ } ++ if (jj.get_src_op () && jj.is_src_ee () && !jj.get_src_intval ()) ++ continue; + -+ ii.merge_values (values); ++ 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 (ii.is_compare ()) -+ continue; ++ /* exclude operations on that symbol. */ + -+ unsigned def = ii.get_def (); -+ if (def) ++ if (j_dst) + { -+ for (int i = 0; i < 16; ++i) -+ if ((1 << i) & def) -+ { -+ values[i] = 0; -+ // invalidate all referring registers -+ for (std::multimap::iterator j = r2r.find (i), k = j; -+ j != r2r.end () && j->first == k->first;) -+ { -+ values[j->second] = INVALID; -+ r2r.erase (j++); -+ } -+ } ++ 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 (ii.is_call ()) -+ continue; -+ -+ // add all referred labels -+ if (ii.is_jump ()) ++ if (j_src) + { -+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end () && i->first == k->first; ++i) ++ int addr = jj.get_src_mem_addr (); ++ if (addr < base) + { -+ todo.insert (i->second); -+ insn_info & jj = infos[i->second]; -+ if (jj.merge_values (values)) -+ ii.clear_visited (); ++ 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; + } -+ continue; + } ++ } + -+ rtx set = single_set (ii.get_insn ()); -+ if (!set) -+ continue; ++ if (freemask && found.size () > 2) ++ { ++ unsigned regno = bit2regno (freemask); ++ /* check again. */ ++ for (std::vector::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 (); + -+ rtx src, dest; -+ if (ii.get_src_autoinc ()) ++ for (std::vector::iterator k = found.begin (); k != found.end (); ++k) + { -+ int regno = ii.get_src_mem_regno (); -+ values[regno] = INVALID; -+ for (std::multimap::iterator j = r2r.find (regno), k = j; -+ j != r2r.end () && j->first == k->first;) -+ { -+ values[j->second] = INVALID; -+ r2r.erase (j++); -+ } ++ insn_info & kk = infos[*k]; ++ kk.absolute2base (regno, base, with_symbol); ++ insn_invalid_p (kk.get_insn (), 0); + } + -+ if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) & ii.get_myuse ())) -+ src = INVALID; ++ // 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); ++ ++ /* mark until last hit is found. */ ++ for (unsigned k = i + 1; k < infos.size (); ++k) + { -+ src = SET_SRC(set); -+ if (ii.is_src_mem () && src->volatil) -+ src = INVALID; ++ infos[k].mark_use (regno); ++ if (k == *found.rbegin ()) ++ break; + } ++ ++change_count; ++ --i; ++ } ++ } ++ ++ 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 fixups; ++ ++ // all paths to check ++ std::vector todo; ++ todo.push_back (index + 1); ++ ++ bool match_size = false; ++ std::set 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) ++ { ++ insn_info & jj = infos[pos]; + -+ if (ii.get_dst_autoinc ()) ++ // check all jumps labels for register usage ++ if (jj.is_label ()) + { -+ int regno = ii.get_dst_mem_regno (); -+ values[regno] = INVALID; -+ for (std::multimap::iterator j = r2r.find (regno), k = j; -+ j != r2r.end () && j->first == k->first;) ++ for (l2j_iterator j = label2jump.find (jj.get_insn ()->u2.insn_uid), k = j; ++ j != label2jump.end () && j->first == k->first; ++j) + { -+ values[j->second] = INVALID; -+ r2r.erase (j++); ++ insn_info * ll = insn2info.find (j->second)->second; ++ if (ll->is_use (regno)) ++ return 0; + } ++ break; + } + -+ if (src == INVALID || ii.get_src_op () || ii.get_dst_autoinc ()) -+ dest = INVALID; -+ else -+ dest = SET_DEST(set); ++ // break if no longer used ++ if (!jj.is_use (regno)) ++ break; + -+ // track register values for now -+ int dregno = ii.get_dst_regno (); -+ int sregno = ii.get_src_regno (); ++ if (jj.in_proepi ()) ++ return 0; + -+ // track r2r -+ if (dregno >= 0 && sregno >= 0) ++ // add all labels ++ if (jj.is_jump ()) + { -+ r2r.insert (std::make_pair (dregno, sregno)); -+ r2r.insert (std::make_pair (sregno, dregno)); ++ for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end () && j->first == k->first; ++j) ++ todo.push_back (j->second); ++ continue; + } + -+ if (sregno >= 0) -+ { -+ values[sregno] = dest; -+ for (unsigned i = sregno + 1; i < END_REGNO (ii.get_src_reg ()); ++i) -+ values[i] = INVALID; -+ } ++ // 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 (dregno >= 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) + { -+ // TODO: check for volatile sources -+ values[dregno] = src; -+ for (unsigned i = dregno + 1; i < END_REGNO (ii.get_dst_reg ()); ++i) -+ values[i] = INVALID; ++ if (jj.get_dst_regno () == regno) ++ return 0; + -+ } -+ } -+ } -+ return 0; -+} ++ if (jj.get_src_mem_addr () < size) ++ 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) - { -+ track_regs (); ++ if (jj.get_src_mem_addr () == size) ++ match_size = true; + - 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))))) ++ fix = true; ++ } ++ if (jj.get_dst_mem_regno () == regno) + { -+ log ("(e) %d: eliminate redundant load to %s\n", index, reg_names[ii.get_dst_regno ()]); -+ SET_INSN_DELETED(insn); -+ ++change_count; -+ continue; - -- continue; ++ 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; + } -+ } - } - return change_count; - } -@@ -3360,8 +3560,8 @@ opt_absolute (void) - - std::vector 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::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 -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 -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); -+ } ++ if (!fix) ++ return 0; + -+ rtx * -+ get_values () const -+ { -+ return values; -+ } ++ fixups.insert (pos); + -+ void -+ set_version (unsigned regno, unsigned ver) -+ { -+ if (regno < FIRST_PSEUDO_REGISTER) -+ versions[regno] = ver; -+ } ++ // done if this is an add ++ if (ii.is_def (regno)) ++ break; ++ } ++ } + -+ 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)); -+ } ++ if (!match_size || !fixups.size ()) ++ return 0; + -+ /* 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; -+ } -+ } ++ if (!ii.make_post_inc (regno)) ++ return 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; -+ } -+}; ++ log ("(i) auto_inc for %s at %d - %d fixups\n", reg_names[regno], index, fixups.size ()); + - /* 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 - { - 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) - { - } - -- 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 ptrdiff_t - operator < (insn_info const & o) const -@@ -744,65 +802,12 @@ class insn_info - a5_to_a7 (rtx a7); - }; - --rtx * --insn_info::get_values () -+track_var * -+insn_info::get_track_var () - { -- 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; - } - - 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; - } - -- // realloc happened... -+// realloc happened... - for (unsigned i = 0; i < infos.size (); ++i) - if (infos[i].get_insn () == this->insn) - return i; - -- // whoops!? -+// whoops!? - return 0; - } - -@@ -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 - } - - 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)); - -- // usage flags did not change -+// usage flags did not change - } - - static -@@ -1363,7 +1368,7 @@ clear (void) - static bool - is_reg_dead (unsigned regno, unsigned _pos) - { -- // 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 () - { -- // 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); - } - -- // add entry point -+// add entry point - std::set todo; - todo.insert (0); - -@@ -3319,7 +3324,7 @@ opt_shrink_stack_frame (void) - static unsigned - track_regs () - { -- // 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); - } - -- rtx * values = (rtx *) xmalloc (FIRST_PSEUDO_REGISTER * sizeof(rtx)); // track register values -+ update_label2jump (); - -- // add entry point -- std::set todo; -- todo.insert (0); -+// add entry point -+ std::map todo; -+ todo.insert (std::make_pair (0, new track_var ())); - - 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 ()); - -- 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 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)); - -+ unsigned version = startpos; ++ // fix all offsets / adds ++ for (std::set::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; ++} ++ ++/* ++ * 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 = startpos; index < infos.size (); ++index) - { - insn_info & ii = infos[index]; - - // already visited? -- if (ii.is_visited () && ii.equal_values (values)) -+ if (ii.is_visited () && ii.get_track_var ()->contains (track)) - break; - -- // 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; - } - -- ii.merge_values (values); -+ // mark current insn_info and set sp_offset -+ ii.mark_visited (); -+ ii.get_track_var ()->assign (track); - - if (ii.is_compare ()) - continue; -@@ -3381,7 +3400,7 @@ track_regs () - for (std::multimap::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; - -+ rtx set = single_set (ii.get_insn ()); ++ update_label2jump (); + - // add all referred labels - if (ii.is_jump ()) - { -+ if (ANY_RETURN_P(ii.get_insn ())) -+ break; ++ for (unsigned index = 0; index < infos.size (); ++index) ++ { ++ insn_info & ii = infos[index]; + - 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 (ii.in_proepi ()) ++ continue; + -+ 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; ++ if (!INSN_P(ii.get_insn ())) ++ continue; + -+ // 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::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::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 -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); ++// // more than one reg used ++// if (ii.get_myuse () & (ii.get_myuse () - 1)) ++// continue; + -+ /* 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); ++// // don't if fp regs are touched ++// if ((ii.get_myuse () & 0xff0000)) ++// continue; + -+ 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 -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 > & 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); ++ 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) ++ { ++ } ++ ++ /* 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; ++ } ++ ++ unsigned int pp; ++ ++ unsigned ++ execute_bbb_optimizations (void); ++ }; ++// class pass_bbb_optimizations ++ ++ /* 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 (;;) + { -+ 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); ++ 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 (); + - 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 -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 -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 -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 -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 -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 -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 > & 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; ++ done = 0, update_insns (); + - 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 (); ++ if (do_autoinc && opt_autoinc ()) ++ done = 0, update_insns (); + -+ /* do not use a4 if compiling baserel */ -+ if (flag_pic >= 3) -+ mask &= ~(1 << PIC_REG); ++ if (do_bb_reg_rename) ++ { ++ while (opt_reg_rename ()) ++ { ++ update_insns (); ++ done = 0; ++ } ++ } + - 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 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 reg2slot; -+ for (unsigned slot = 0; slot < FIRST_PSEUDO_REGISTER; ++slot) -+ if (values[slot]) ++ if (done) ++ break; ++ } ++ ++ if (do_shrink_stack_frame) + { -+ 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)); ++ if (opt_shrink_stack_frame ()) ++ update_insns (); + } - - 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::iterator j = r2r.find (i), k = j; -- j != r2r.end () && j->first == k->first;) -+ for (std::multimap::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::iterator j = r2r.find (regno), k = j; -- j != r2r.end () && j->first == k->first;) -+ for (std::multimap::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::iterator j = r2r.find (regno), k = j; -- j != r2r.end () && j->first == k->first;) -+ for (std::multimap::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)); + -+ 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 -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 -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 todo; -+ std::multimap 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 -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 -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 -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 -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; ++ /* 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; + } + -+ inline rtx -+ get_dst_mem_reg () const -+ { -+ return dst_mem_reg; -+ } ++} // anon namespace ++ ++rtl_opt_pass * ++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) ++ 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); + - inline int - get_src_intval () const - { -@@ -762,6 +774,12 @@ class insn_info - void - scan_rtx (rtx); - -+ void -+ make_post_inc (int regno); ++ rtx pat0 = gen_rtx_SET(reg, *src); ++ //rtx_insn * n0 = ++ emit_insn_before (pat0, insn); + -+ void -+ auto_inc_fixup (int regno, int size); ++ rtx pat1 = gen_rtx_SET(dest, reg); ++ //rtx_insn * n1 = ++ emit_insn_before (pat1, insn); + - /* 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); ++ SET_INSN_DELETED(insn); ++ } ++ } ++ } ++ } + -+ (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode); -+} ++ return 0; ++ } + -+void -+insn_info::auto_inc_fixup (int regno, int size) -+{ -+// debug_rtx (insn); ++} // anon namespace + -+ rtx set = single_set (insn); ++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" + + /* 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); + -+ if (is_compare ()) -+ set = SET_SRC(set); ++ tree returned_attrs = decl_attributes (node, attributes, flags); + -+ // add to register -+ if (get_src_regno () == regno) ++#ifdef TARGET_AMIGA ++ /* add an attribute to the function decl's type if there are asm register parameters. */ ++ if (TREE_CODE (*node) == FUNCTION_DECL) + { -+ rtx src = SET_SRC(set); -+ if (get_src_intval () == size) ++ char const * synthetic = ""; ++ for (tree params = TYPE_ARG_TYPES(TREE_TYPE(*node)); params; params = TREE_CHAIN(params)) + { -+ src_intval = 0; -+ src_plus = false; -+ SET_SRC(set) = XEXP(src, 0); ++ 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))); + } -+ else -+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size); + } -+ else ++#endif ++ ++ return returned_attrs; + } + + +@@ -5024,6 +5051,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 +5091,59 @@ push_parm_decl (const struct c_parm *parm, tree *expr) + + decl = pushdecl (decl); + ++#ifdef TARGET_AMIGAOS ++ if (parm->asmspec) + { -+ 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); ++ tree atype = TREE_TYPE(decl); ++ const char *asmspec = TREE_STRING_POINTER(parm->asmspec); ++ if (*asmspec == '%') ++ ++asmspec; ++ int reg_number = decode_reg_name (asmspec); + -+ rtx plus = XEXP(mem, 0); -+ if ((get_dst_mem_regno () == regno ? dst_mem_addr : src_mem_addr) == size) ++ /* 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 + { -+ 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; ++ /* 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); + } -+ 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); -+} ++#endif + - track_var * - insn_info::get_track_var () + 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 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; + } + + /* 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) { -@@ -1126,7 +1202,7 @@ temp_reg_rename (std::vector > & 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; - } ++ 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; } -@@ -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))); ++ ++ // 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 + }; - 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))); + /* 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, + { + rtx_insn *insn; - /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax) */ - if (src_op) ++#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 ++ + /* Replace references to LABEL1 with LABEL2. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) { - 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); - } - } +@@ -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); -@@ -1347,7 +1423,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol) - } + 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; + } -- 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; +@@ -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"); -@@ -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)); ++/** ++ * 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); + } -- rtx_insn * subinsn = make_insn_raw (gen_rtx_SET (copyreg, sub)); -+ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub)); +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; - 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); + #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 */ + } + } -- 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))); +@@ -1608,6 +1618,11 @@ main (int argc, char **argv) - emit_insn_before (neu, i2.get_insn ()); + fprintf (stderr, "\n"); + } ++ /* begin-GG-local: dynamic libraries */ ++#ifdef COLLECT2_PRELINK_HOOK ++ COLLECT2_PRELINK_HOOK(ld1_argv, &strip_flag); ++#endif ++ /* end-GG-local */ -@@ -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); + /* Load the program, searching all libraries and attempting to provide + undefined symbols from repository information. +@@ -1648,6 +1663,8 @@ main (int argc, char **argv) + } + } - // 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; ++ /* 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 */ - 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; - } + /* 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) -@@ -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); + 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; + } -- 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) +@@ -1821,6 +1847,11 @@ main (int argc, char **argv) + maybe_unlink (export_file); + #endif - 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; ++ /* begin-GG-local: dynamic libraries */ ++#ifdef COLLECT2_EXTRA_CLEANUP ++ COLLECT2_EXTRA_CLEANUP(); ++#endif ++ /* end-GG-local */ + return 0; } -+/* -+ * 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]; +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. ++ 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. + -+ if (ii.in_proepi ()) -+ continue; ++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. */ + -+ 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; ++#undef TARGET_AMIGAOS ++#define TARGET_AMIGAOS 1 + -+ int regno = REGNO(reg); -+ int size = GET_MODE_SIZE(ii.get_mode ()); -+ if (size > 4) -+ continue; ++extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree, tree); + -+// log ("starting auto_inc search for %s at %d\n", reg_names[regno], index); ++/* 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. */ + -+ // track all fixups to modify -+ std::set fixups; ++#undef INIT_CUMULATIVE_ARGS ++#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ ++ (amigaos_init_cumulative_args(&(CUM), (FNTYPE), (INDIRECT))) + -+ // all paths to check -+ std::vector todo; -+ todo.push_back (index + 1); ++#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). + -+ bool match_size = false; -+ bool ok = true; -+ std::set visited; -+ while (ok && todo.size () > 0) -+ { -+ unsigned pos = todo[todo.size () - 1]; -+ todo.pop_back (); ++ This file is part of GCC. + -+ if (pos == index) -+ { -+ ok = false; -+ break; -+ } ++ 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 (visited.find (pos) != visited.end ()) -+ continue; -+ visited.insert (pos); ++ 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. + -+ for (; pos < infos.size (); ++pos) -+ { -+ insn_info & jj = infos[pos]; ++ 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. */ + -+ // run over labels -+ if (jj.is_label ()) -+ continue; ++//work without flag_writable_strings which is not in GCC4 ++#define REGPARMS_68K 1 + -+ // break if no longer user -+ if (!jj.is_use (regno)) -+ break; ++#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 "langhooks.h" ++#include "function.h" ++#include "config/m68k/amigaos.h" + -+ if (jj.in_proepi ()) -+ { -+ ok = false; -+ break; -+ } ++//#define MYDEBUG 1 ++#ifdef MYDEBUG ++#define DPRINTF(x) printf x; fflush(stdout); ++#else ++#define DPRINTF(x) ++#endif + -+ // 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; -+ } ++//int amiga_declare_object; + -+ // not used directly -+ if (!jj.is_myuse (regno)) -+ continue; ++#if 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) -+ { -+ if (jj.get_src_intval () < size || (jj.get_dst_mem_regno () == regno && jj.get_dst_addr () < size)) -+ { -+ ok = false; -+ break; -+ } ++//----- from 68k.c start + -+ if (jj.get_dst_addr () == size) -+ match_size = true; ++/* Stack checking and automatic extension support. */ + -+ fixups.insert (pos); -+ // end chain, if self assign -+ if (jj.get_dst_regno () == regno) -+ break; ++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); ++ } ++ } + -+ continue; -+ } + -+ if (jj.get_dst_mem_regno () == regno) ++//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, othercum; ++ ++/* 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 = 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 %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. ++ For a library call, FNTYPE is 0. */ ++ ++ cum->last_arg_reg = -1; ++ cum->regs_already_used = 0; ++ ++ if (fntype) ++ { ++ tree attrs = TYPE_ATTRIBUTES(fntype); ++ if (attrs) ++ { ++ 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) + { -+ if (jj.get_dst_addr () < size) ++ tree args = TREE_VALUE(ratree); ++ ++ if (args && TREE_CODE (args) == TREE_LIST) + { -+ ok = false; -+ break; ++ 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; ++ } + } -+ if (jj.get_dst_addr () == size) -+ match_size = true; -+ fixups.insert (pos); + } + } + } ++ } ++ else ++ /* Libcall. */ ++ cum->num_of_regs = 0; + -+ if (!ok || !match_size || !fixups.size ()) -+ continue; -+ -+ log ("(i) auto_inc for %s at %d\n", reg_names[regno], index); -+ -+ ii.make_post_inc (regno); -+ -+ // fix all offsets / adds -+ for (std::set::iterator k = fixups.begin (); k != fixups.end (); ++k) ++ 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) + { -+// log ("(i) fixup at %d\n", *k); ++ next_param = TREE_CHAIN(param); ++ if (!next_param && TREE_VALUE (param) != void_type_node) ++ cum->num_of_regs = 0; ++ } ++ } + -+ insn_info & kk = infos[*k]; ++#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 + -+ kk.auto_inc_fixup (regno, size); -+ } -+ ++change_count; -+ --index; // rerun insn to check src and dst ++ if (fntype && DECL_STATIC_CHAIN(fntype)) ++ { ++ rtx reg = amigaos_static_chain_rtx (decl, 0); ++ if (reg) ++ cum->regs_already_used |= (1 << REGNO(reg)); + } + -+ return change_count; ++ 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)); +} + - namespace - { - -@@ -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, '+'); - - 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 (); - -+ if (do_autoinc && opt_autoinc ()) -+ done = 0, update_insns (); ++int ++amigaos_function_arg_reg (unsigned regno) ++{ ++ return (mycum.regs_already_used & (1 << regno)) != 0; ++} + - if (do_bb_reg_rename) - { - while (opt_reg_rename ()) - -From 210ee63e6fd9926deb41a28130f5c1b5e1dde8ba Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 ()); ++/* Update the data in CUM to advance over an argument. */ + - /* 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::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); - } ++void ++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. */ + - ++change_count; - --index; // rerun insn to check src and dst - } - -From f0beccad3618cddcc3744347b5e000251394e1f4 Mon Sep 17 00:00:00 2001 -From: bebbo -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 - #include - -+static int xx = 0; ++ DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cum)); + - bool be_very_verbose; - bool be_verbose; - -@@ -1487,7 +1489,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|%d\t", ii.get_index ()); - - 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); - } - -- // 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 & found, unsigned start, unsigned rename_regno) - { - unsigned startm1 = start - 1; - -- /* already searched. */ -- if (found.find (startm1) != found.end ()) -- break; -+// /* already searched. */ -+// if (found.find (startm1) != found.end ()) -+// break; - - /* do not run over RETURNS */ - insn_info & jj = infos[start]; ++ 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; ++ } + -+ /* stop at labels. If a label is a start pos, a search is maybe started again. */ -+ if (jj.is_label ()) -+ break; ++ if (cum->formal_type) ++ cum->formal_type = TREE_CHAIN(cum->formal_type); ++} + - 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 & found, unsigned start, unsigned rename_regno) - static unsigned - opt_reg_rename (void) - { -+ 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); ++/* 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. + - start = find_start (found, start, rename_regno); - todo.insert (start); - } ++ 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. */ + -+ /* 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; ++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)); + -+ if (bb.is_use (rename_regno)) -+ { -+ unsigned start = find_start (found, pos - 1, rename_regno); -+ todo.insert (start); -+ } -+ } ++ if (cum->num_of_regs) ++ { ++ int regbegin = -1, altregbegin = -1, len; + - 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, '+'); - -+ ++xx; -+ printf ("x: %d\n", xx); -+// if (xx <= 90 || xx > 93) -+// do_bb_reg_rename = false; ++ /* 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 (be_very_verbose) - log ("ENTER\n"); - - -From 77e758b888024c9df2267f0e344ff46efa763951 Mon Sep 17 00:00:00 2001 -From: bebbo -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; ++ if (regbegin != -1) ++ { ++ int reg; ++ long mask; ++ ++ look_for_reg: mask = 1 << regbegin; ++ for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1) ++ if (!(cum->regs_already_used & mask)) ++ { ++ int end; ++ for (end = reg; end < cum->num_of_regs && end < reg + len; end++, mask <<= 1) ++ if (cum->regs_already_used & mask) ++ break; ++ if (end == reg + len) ++ { ++ cum->last_arg_reg = reg + regbegin; ++ cum->last_arg_len = len; ++ break; ++ } ++ } ++ ++ if (reg == cum->num_of_regs && altregbegin != -1) ++ { ++ 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. */ + -+ update_label2jump(); ++struct rtx_def * ++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)); + - 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 -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 -+ { -+ ok = false; -+ break; -+ } - - // 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 -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; -+ } - - // break if no longer used - if (!jj.is_use (regno)) - -From bc3028a6f267699e0d6556b310a5cb75c2600e22 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 -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(+) - -diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h -index d711530d0535..4f08f81a3ae0 100644 ---- gcc/ginclude/stddef.h -+++ gcc/ginclude/stddef.h -@@ -325,6 +325,7 @@ typedef __rune_t rune_t; - #define __WCHAR_TYPE__ int - #endif - #ifndef __cplusplus -+#define _WCHAR_T_ int - typedef __WCHAR_TYPE__ wchar_t; - #endif - #endif - -From 3362e147aee470ae0715005e851264a30634aefc Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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); ++ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum; + - 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 -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 -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 -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 -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 -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; - - // 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; - } -@@ -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 ()); ++ 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 (asmtree && 0 == strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree)))) + { -+ 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, "%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 positions; - std::vector > locs; - std::vector > patch; - bool ok = true; -@@ -2138,6 +2144,7 @@ opt_reg_rename (void) - *j->first = j->second; - } - -+ 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); - -+ if (be_verbose) ++ 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))) + { -+ for (std::vector::iterator i = positions.begin (); i != positions.end (); ++i) -+ printf ("%d ", *i); -+ printf ("\n"); -+ fflush (stdout); ++ error ("two parameters allocated for one register"); ++ break; + } ++ cum->regs_already_used |= (1 << (cum->last_arg_reg + i)); ++ } ++ return gen_rtx_REG (mode, cum->last_arg_reg); ++ } ++ return _m68k_function_arg (cum, mode, type); ++} + - /* apply all changes. */ - for (std::vector >::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; - - 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 -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; - } - -+ if (code == TRAP_IF) ++void ++amiga_emit_regparm_clobbers (void) ++{ ++ 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)))); ++ } ++} ++ ++/* 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) + { -+ /* mark all registers used. */ -+ hard = use = myuse = (1 << FIRST_PSEUDO_REGISTER) - 1; -+ return; -+ } ++ tree attrs1 = TYPE_ATTRIBUTES(type1); + - const char *fmt = GET_RTX_FORMAT(code); - for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - -From dccd1ea371e35241057b86bdf90cf8be60d2083c Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 (); - -- 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 (); - - if (do_autoinc && opt_autoinc ()) -@@ -4246,6 +4247,10 @@ namespace - if (opt_shrink_stack_frame ()) - update_insns (); - } ++ tree asm1 = lookup_attribute("asmregs", attrs1); ++ tree stack1 = lookup_attribute("stkparm", attrs1); ++ tree reg1 = lookup_attribute("regparm", attrs1); + -+ /* 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 -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 & found, unsigned start, unsigned rename_regno) -+find_start (unsigned start, unsigned rename_regno) - { - /* search the start. */ - while (start > 0) - { - 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); - -- 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 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 (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); ++ 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) ++ { ++ 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 (reg2) ++ { ++ if (stack1 || asm1) ++ return 0; ++ ++ int no2 = TREE_INT_CST_LOW(TREE_VALUE(reg2)); ++ return amigaos_regparm == no2; ++ } ++ ++ if (stack1) { ++ if (stack2) ++ return 1; ++ return amigaos_regparm == 0; ++ } + -+ 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); - } - } - -@@ -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); - } - } - -From 5180bf61c8f24d190fe51722d78f69b4fb566065 Mon Sep 17 00:00:00 2001 -From: bebbo -Date: Wed, 5 Jul 2017 20:20:50 +0200 -Subject: [PATCH 197/303] @B add ctype::~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::~ctype() -+ { -+ } ++ if (stack2) ++ return amigaos_regparm == 0; + - char - ctype::do_toupper(char __c) const - { - -From f088c99da4c5cdb2b86c57475a2fddbb76deba6f Mon Sep 17 00:00:00 2001 -From: bebbo -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::~ctype() - { -+ _S_destroy_c_locale(_M_c_locale_ctype); -+ if (_M_del) -+ delete[] this->table(); - } -+#endif - - char - ctype::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::table_size; - -+#ifndef TARGET_AMIGA -+/* moved to ctype_configure_char */ - ctype::~ctype() - { - _S_destroy_c_locale(_M_c_locale_ctype); - if (_M_del) - delete[] this->table(); - } -+#endif - - // 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 -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 -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; - } - --#ifdef TARGET_AMIGA -+#ifdef __AMIGA__ - ctype::~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 - - const size_t ctype::table_size; - --#ifndef TARGET_AMIGA -+#ifndef __AMIGA__ - /* moved to ctype_configure_char */ - ctype::~ctype() - { - -From 8e243494b547e0452be69f9decc094f5cdf390db Mon Sep 17 00:00:00 2001 -From: bebbo -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 (); ++ if (asm1) ++ { ++ if (!asm2) ++ return 0; + -+ // but still check for usage after this jump -+ j2l_iterator l = jump2label.find(index + 2); -+ if (l == jump2label.end()) -+ continue; ++ return 0 == strcmp(IDENTIFIER_POINTER(TREE_VALUE(asm1)), IDENTIFIER_POINTER(TREE_VALUE(asm2))); ++ } + -+ 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; - -- 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; - - rtx jmpsrc = XEXP(jmppattern, 1); - -From be3b4203f780465f6221fe829df769638bb989c6 Mon Sep 17 00:00:00 2001 -From: bebbo -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 */ ++ if (asm2) ++ return 0; + -+#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); ++ } ++ else ++ { ++ tree attrs1 = TYPE_ATTRIBUTES(type1); + -+ 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 - } - - switch_to_section (eh_frame_section); - -From 7c0d506d800c3a33d3a9f8b7da0a5be3e4a72178 Mon Sep 17 00:00:00 2001 -From: bebbo -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 - - /* 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); - - 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++; ++ tree chip1 = lookup_attribute("chip", attrs1); ++ tree fast1 = lookup_attribute("fast", attrs1); ++ tree far1 = lookup_attribute("far", attrs1); + -+#ifdef TARGET_AMIGA ++ 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 */ ++ ++/* 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) ++{ ++ 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)) ++ { ++ 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 + { -+ 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; ++ if (is_attribute_p ("chip", name) || is_attribute_p ("fast", name) || is_attribute_p ("far", name)) ++ { ++ // OK ++ } ++ else ++ { ++ warning (OPT_Wattributes, "`%s' attribute only applies to functions", IDENTIFIER_POINTER(name)); ++ } + } -+#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++); ++ return NULL_TREE ; + } ++ while (0); ++ // error case ++ *no_add_attrs = true; ++ return NULL_TREE ; +} + -+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 ++#define AMIGA_CHIP_SECTION_NAME ".datachip" ++#define AMIGA_FAST_SECTION_NAME ".datafast" ++#define AMIGA_FAR_SECTION_NAME ".datafar" + - -From 54f7a6eb27c74a7f4358a32c4f018ca12512bab0 Mon Sep 17 00:00:00 2001 -From: bebbo -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 - { -- 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) -+ { -+ 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 - - -From 68afa4d4843d806f89436406aa175babaf951e33 Mon Sep 17 00:00:00 2001 -From: bebbo -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(-) - -diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in -index f09b39b0e85f..39f91d1567b6 100644 ---- libgcc/Makefile.in -+++ libgcc/Makefile.in -@@ -230,7 +230,7 @@ endif - # Options to use when compiling libgcc2.a. - # - LIBGCC2_DEBUG_CFLAGS = -g --LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ -+LIBGCC2_CFLAGS = $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ - $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \ - -fbuilding-libgcc -fno-stack-protector \ - $(INHIBIT_LIBC_CFLAGS) -@@ -284,7 +284,7 @@ INTERNAL_CFLAGS = $(CFLAGS) $(LIBGCC2_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ - $(INCLUDES) @set_have_cc_tls@ @set_use_emutls@ - - # Options to use when compiling crtbegin/end. --CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ -+CRTSTUFF_CFLAGS = $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \ - $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \ - -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 -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 -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) ++void ++amiga_insert_attribute (tree decl, tree * attr) ++{ ++ if (!*attr) + 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]; ++ tree name = TREE_PURPOSE(*attr); + -+ unsigned short count = 0; -+ unsigned short reg_mask = masks[index]; -+ /* init each index once. */ -+ if (!reg_mask) ++ if (is_attribute_p("chip", name) || is_attribute_p("far", name) || is_attribute_p("fast", name)) + { -+ /* get the return address.*/ -+ unsigned short * sp = *(((unsigned short **)¤t) - 1); -+ /* search the movem -x(a5),regs insn.*/ -+ for (;;) ++ if (!TREE_TYPE(decl) == VAR_DECL) + { -+ unsigned short s = *sp++; -+// printf("%04x ", s); -+ gcc_assert(s != (unsigned short)0x4e75);// hit return? ouch! -+ if (s == (unsigned short)0x4ced) -+ break; ++ error ("`%s' attribute can only be specified for variables", IDENTIFIER_POINTER(name)); ++ return; + } -+ reg_mask = *sp; -+ /* count saved regs */ -+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i) ++ ++ if (! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)) + { -+ if (m & 1) -+ ++count; -+ m >>= 1; ++ error ("`%s' attribute cannot be specified for local variables", IDENTIFIER_POINTER(name)); ++ return; + } -+ masks[index] = reg_mask; -+ counts[index] = count; ++ ++ 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 unknown", IDENTIFIER_POINTER(name)); + } ++} ++ ++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. */ ++#ifndef TARGET_AMIGAOS_VASM ++extern void ++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"; ++ ++ 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 -+ count = counts[index]; ++ 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"; + -+ /* regs are saved below local vars -> start at current */ -+ int * p = ((int *)current) - count; ++ 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 + -+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i) ++/* Baserel support. */ ++ ++/** ++ * Does x reference the pic_reg and is const or plus? ++ */ ++static int ++_amiga_is_const_pic_ref (const_rtx x) ++{ ++ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS) + { -+ 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; ++ if (GET_CODE(XEXP(x, 1)) == CONST_INT) ++ return _amiga_is_const_pic_ref(XEXP(x, 0)); ++ 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; - -- 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 -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 -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 -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 -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 -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 -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 ---- libgcc/config.host -+++ libgcc/config.host -@@ -816,8 +816,8 @@ 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" - ;; - m68k-*-elf* | fido-*-elf) - tmake_file="$tmake_file m68k/t-floatlib" - -From cfa7b74b520032da16a32425a6d206cba92d0feb Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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)) ++ ++ 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) ++{ ++ if (flag_pic < 3) ++ return false; ++ 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. ++ ++ 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; ++} ++ ++rtx ++amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED) ++{ ++ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM); ++} ++ ++rtx ++amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED) ++{ ++ if (!decl || !DECL_STATIC_CHAIN(decl)) ++ return 0; ++ ++ 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; ++ ++ unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low; ++ used |= 1 << regno; ++ } ++ ++ 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 0; ++} ++ ++/** ++ * 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") ) ++ (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") ) ++ (const_int 0 [0]) ++ ] 6) ++ (const_int 1234 [0xe00]))))))) xyz.c:41 465 {*lea} ++ + */ +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 (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 (amiga_is_const_pic_ref(x)) ++ return GET_CODE(y) == CONST_INT; ++ ++ return amigaos_legitimate_src(x) && amigaos_legitimate_src(y) && !amiga_is_const_pic_ref(y); ++ } ++ ++ if (GET_CODE(src) == CONST) ++ { ++ rtx op = XEXP(src, 0); ++ if (GET_CODE(op) == MINUS || GET_CODE(op) == PLUS) ++ { ++ rtx x = XEXP(op, 0); ++ if (GET_CODE(x) == NOT || GET_CODE(x) == NEG || GET_CODE(x) == SIGN_EXTEND) ++ { ++ rtx reg = XEXP(x, 0); ++ if (!REG_P(reg)) ++ return true; ++ ++ return false; ++ } ++ } ++ ++ if (GET_CODE(op) == UNSPEC) ++ return false; ++ } ++ ++ return true; ++} ++ ++void ++amigaos_restore_a4 (void) ++ { ++ if (flag_pic >= 3 && !flag_resident) ++ { ++ 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 ___a4_init,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 ++ } ++ ++#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. ++ ++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 TARGET_AMIGAOS ++#define TARGET_AMIGAOS 1 ++#endif ++ ++#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 ++ ++/* 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) ++ ++#endif ++ ++/* Compile using the first 'm68k_regparm' data, address and float ++ registers for arguments passing. */ ++/*#define SUBTARGET_OPTIONS { "regparm=", &m68k_regparm_string, \ ++ N_("Use this register count to pass arguments"), 0},*/ ++ ++ ++/* Nonzero if we need to generate special stack-allocating insns. ++ On most systems they are not needed. ++ When they are needed, also define ALTERNATE_ALLOCATE_STACK (see m68k.md) ++ to perform the necessary actions. */ ++//#undef TARGET_ALTERNATE_ALLOCATE_STACK ++//#define TARGET_ALTERNATE_ALLOCATE_STACK 0 ++ ++ ++/* 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") } ++ ++ ++/* 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); ++ ++#undef TARGET_ASM_NAMED_SECTION ++#define TARGET_ASM_NAMED_SECTION amiga_named_section + -+ x = XEXP(x, 1); -+ if (GET_CODE(x) != CONST) -+ return true; ++/* Various ABI issues. */ + -+ x = XEXP(x, 0); -+ if (GET_CODE(x) != MINUS) -+ return true; ++/* This is (almost;-) BSD, so it wants DBX format. */ ++#undef DBX_DEBUGGING_INFO ++#define DBX_DEBUGGING_INFO + -+ x = XEXP(x, 0); -+ if (GET_CODE(x) != NOT) -+ return true; ++/* GDB goes mad if it sees the function end marker. */ + -+ x = XEXP(x, 0); -+ return !REG_P(x); -+} -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); ++#define NO_DBX_FUNCTION_END 1 + -+#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 -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 -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 -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; - } - } ++/* Allow folding division by zero. */ + -+ if (code == CLOBBER) -+ def |= use; - } - - void - -From 821e16347528355a29fdcfd521f7cdb26414a67f Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 -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 ---- libgcc/config/m68k/fpgnulib.c -+++ libgcc/config/m68k/fpgnulib.c -@@ -105,6 +105,7 @@ union long_double_long - - #ifndef EXTFLOAT - -+#ifdef __UNORDSF2 - int - __unordsf2(float a, float b) - { -@@ -118,7 +119,9 @@ __unordsf2(float a, float b) - return 1; - return 0; - } -+#endif - -+#ifdef __UNORDDF2 - int - __unorddf2(double a, double b) - { -@@ -134,7 +137,9 @@ __unorddf2(double a, double b) - return 1; - return 0; - } -+#endif - -+#ifdef __FLOATUNSIDF - /* convert unsigned int to double */ - double - __floatunsidf (unsigned long a1) -@@ -167,7 +172,9 @@ __floatunsidf (unsigned long a1) - - return dl.d; - } -+#endif - -+#ifdef __FLOATSIDF - /* convert int to double */ - double - __floatsidf (long a1) -@@ -213,7 +220,9 @@ __floatsidf (long a1) - - return dl.d; - } ++#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 ++ ++/* 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) ++ ++/* 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 ++ ++#undef M68K_REGNAME ++#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. */ ++ ++#undef PCC_STATIC_STRUCT_RETURN ++ ++/* Setup a default shell return value for those (gazillion..) programs that ++ (inspite of ANSI-C) declare main() to be void (or even VOID...) and thus ++ cause the shell to randomly caugh upon executing such programs (contrary ++ to Unix, AmigaOS scripts are terminated with an error if a program returns ++ with an error code above the `error' or even `failure' level ++ (which is configurable with the FAILAT command)). */ ++ ++//+2004-06-24 Ulrich Weigand ++//+ ++//+ * c-decl.c (finish_function): Do not check for DEFAULT_MAIN_RETURN. ++//+ * system.h (DEFAULT_MAIN_RETURN): Poison. ++//+ * doc/tm.texi (DEFAULT_MAIN_RETURN): Remove documentation. ++//+ ++ ++//poison VAR ++//#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node) ++ ++#undef WCHAR_TYPE ++#define WCHAR_TYPE "unsigned short" ++ ++/* 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 ++ ++#undef TARGET_ASM_EH_FRAME_SECTION ++#define TARGET_ASM_EH_FRAME_SECTION amiga_eh_frame_section +#endif - -+#ifdef __FLOATUNSISF - /* convert unsigned int to float */ - float - __floatunsisf (unsigned long l) -@@ -221,7 +230,10 @@ __floatunsisf (unsigned long l) - double foo = __floatunsidf (l); - return foo; - } ++ ++/* Use sjlj exceptions because dwarf work only on elf targets */ ++#undef DWARF2_UNWIND_INFO ++#define DWARF2_UNWIND_INFO 0 ++ ++ ++/* This is how to output an assembler line that says to advance the ++ location counter to a multiple of 2**LOG bytes. */ ++ ++#ifndef ALIGN_ASM_OP ++#define ALIGN_ASM_OP "\t.align\t" +#endif - + -+#ifdef __FLOATSISF - /* convert int to float */ - float - __floatsisf (long l) -@@ -229,7 +241,10 @@ __floatsisf (long l) - double foo = __floatsidf (l); - return foo; - } -+#endif ++/* 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) ++ ++#if 0 ++ ++/* 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) ++ + - -+#ifdef __EXTENDSFDF2 - /* convert float to double */ - double - __extendsfdf2 (float a1) -@@ -268,7 +283,9 @@ __extendsfdf2 (float a1) - - return dl.d; - } -+#endif - -+#ifdef __TRUNCDFSF2 - /* convert double to float */ - float - __truncdfsf2 (double a1) -@@ -336,7 +353,9 @@ __truncdfsf2 (double a1) - fl.l = PACK (SIGND (dl1), exp, mant); - return (fl.f); - } -+#endif - -+#ifdef __FIXDFSI - /* convert double to int */ - long - __fixdfsi (double a1) -@@ -368,7 +387,9 @@ __fixdfsi (double a1) - - return (SIGND (dl1) ? -l : l); - } -+#endif - -+#ifdef __FIXSFSI - /* convert float to int */ - long - __fixsfsi (float a1) -@@ -376,6 +397,7 @@ __fixsfsi (float a1) - double foo = a1; - return __fixdfsi (foo); - } ++/* Stack checking and automatic extension support. */ ++ ++#define PROLOGUE_BEGIN_HOOK(STREAM, FSIZE) \ ++ (amigaos_prologue_begin_hook ((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) ++ ++#if 0 ++#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) +#endif - - #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 -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 -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); - long __fixdfsi (double); - long __fixsfsi (float); - -+#if !defined(EXTFLOATCMP) + - int - __unordxf2(long double a, long double b) - { -@@ -467,38 +469,6 @@ __extenddfxf2 (double d) - return ldl.ld; - } - --/* convert long double to double */ --double --__truncxfdf2 (long double ld) --{ -- register long exp; -- register union double_long dl; -- register union long_double_long ldl; -- -- ldl.ld = ld; -- /*printf ("xfdf in: %s\n", dumpxf (ld));*/ -- -- dl.l.upper = SIGNX (ldl); -- if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle && !ldl.l.lower) -- { -- dl.l.lower = 0; -- return dl.d; -- } -- -- exp = EXPX (ldl) - EXCESSX + EXCESSD; -- /* ??? quick and dirty: keep `exp' sane */ -- if (exp >= EXPDMASK) -- exp = EXPDMASK - 1; -- dl.l.upper |= exp << (32 - (EXPDBITS + 1)); -- /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */ -- dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1); -- dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1)); -- dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1); -- -- /*printf ("xfdf out: %g\n", dl.d);*/ -- return dl.d; --} -- - /* convert a float to a long double */ - long double - __extendsfxf2 (float f) -@@ -571,6 +541,8 @@ __negxf2 (long double x1) - return - (double) x1; - } - -+#else ++/* begin-GG-local: dynamic libraries */ + - long - __cmpxf2 (long double x1, long double x2) - { -@@ -613,5 +585,38 @@ __gexf2 (long double x1, long double x2) - return __cmpdf2 ((double) x1, (double) x2); - } - -+/* convert long double to double */ -+double -+__truncxfdf2 (long double ld) -+{ -+ register long exp; -+ register union double_long dl; -+ register union long_double_long ldl; ++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 *); + -+ ldl.ld = ld; -+ /*printf ("xfdf in: %s\n", dumpxf (ld));*/ ++/* This macro is used to check if all collect2 facilities should be used. ++ We need a few special ones, like stripping after linking. */ + -+ dl.l.upper = SIGNX (ldl); -+ if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle && !ldl.l.lower) -+ { -+ dl.l.lower = 0; -+ return dl.d; -+ } ++#define DO_COLLECTING (do_collecting || amigaos_do_collecting()) ++#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) //new + -+ exp = EXPX (ldl) - EXCESSX + EXCESSD; -+ /* ??? quick and dirty: keep `exp' sane */ -+ if (exp >= EXPDMASK) -+ exp = EXPDMASK - 1; -+ dl.l.upper |= exp << (32 - (EXPDBITS + 1)); -+ /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */ -+ dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1); -+ dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1)); -+ dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1); ++/* This macro is called in collect2 for every GCC argument name. ++ ARG is a part of commandline (without '\0' at the end). */ + -+ /*printf ("xfdf out: %g\n", dl.d);*/ -+ return dl.d; -+} -+#endif /* EXTFLOATCMP */ ++#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG) + - #endif /* !__mcoldfire__ */ - #endif /* EXTFLOAT */ -diff --git a/libgcc/config/m68k/t-floatlib b/libgcc/config/m68k/t-floatlib -index 42f6cf97ef48..2365433a59b3 100644 ---- libgcc/config/m68k/t-floatlib -+++ libgcc/config/m68k/t-floatlib -@@ -6,51 +6,57 @@ - # _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 = 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 ++/* 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. */ + -+xfpgnulib__unordsf2.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __UNORDSF2' > xfpgnulib__unordsf2.c -+ cat $< >> xfpgnulib__unordsf2.c ++#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \ ++amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP)) + -+xfpgnulib__unorddf2.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __UNORDDF2' > xfpgnulib__unorddf2.c -+ cat $< >> xfpgnulib__unorddf2.c ++/* This macro is called just after the first linker invocation, in place of ++ "nm" and "ldd". OUTPUT_FILE is the executable's filename. */ + -+xfpgnulib__floatunsidf.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __FLOATUNSIDF' > xfpgnulib__floatunsidf.c -+ cat $< >> xfpgnulib__floatunsidf.c ++#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) ++/* end-GG-local */ + -+xfpgnulib__floatsidf.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __FLOATSIDF' > xfpgnulib__floatsidf.c -+ cat $< >> xfpgnulib__floatsidf.c ++#endif + -+xfpgnulib__floatunsisf.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __FLOATUNSISF' > xfpgnulib__floatunsisf.c -+ cat $< >> xfpgnulib__floatunsisf.c ++/* begin-GG-local: explicit register specification for parameters */ + -+xfpgnulib__floatsisf.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __FLOATSISF' > xfpgnulib__floatsisf.c -+ cat $< >> xfpgnulib__floatsisf.c ++/* Note: this is an extension of m68k_args */ + -+xfpgnulib__extendsfdf2.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __EXTENDSFDF2' > xfpgnulib__extendsfdf2.c -+ cat $< >> xfpgnulib__extendsfdf2.c + -+xfpgnulib__truncdfsf2.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __TRUNCDFSF2' > xfpgnulib__truncdfsf2.c -+ cat $< >> xfpgnulib__truncdfsf2.c ++#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)) + -+xfpgnulib__fixdfsi.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __FIXDFSI' > xfpgnulib__fixdfsi.c -+ cat $< >> xfpgnulib__fixdfsi.c + -+xfpgnulib__fixsfsi.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define __FIXSFSI' > xfpgnulib__fixsfsi.c -+ cat $< >> xfpgnulib__fixsfsi.c ++/* ++ 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. ++*/ + -+xfpgnulib.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define EXTFLOAT' > xfpgnulib.c -+ cat $< >> xfpgnulib.c ++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*); + -+xfpgnulib__cmpxf2.c: $(srcdir)/config/m68k/fpgnulib.c -+ echo '#define EXTFLOAT' > xfpgnulib__cmpxf2.c -+ echo '#define EXTFLOATCMP' >> xfpgnulib__cmpxf2.c -+ cat $< >> xfpgnulib__cmpxf2.c -+ -\ No newline at end of file - -From 97a50aa76b592060171013c4a00ac472d8711580 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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 -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 --#include --#include -- --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); ++/* 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.) */ + - 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); ++#undef TARGET_FUNCTION_ARG_ADVANCE ++#define TARGET_FUNCTION_ARG_ADVANCE amigaos_function_arg_advance + - // 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); ++/* A C expression that controls whether a function argument is passed ++ in a register, and which register. */ + - 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; -+ } ++#undef TARGET_FUNCTION_ARG ++#define TARGET_FUNCTION_ARG amigaos_function_arg + -+ 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); ++#undef TARGET_PACK_CUMULATIVE_ARGS ++#define TARGET_PACK_CUMULATIVE_ARGS(CUM) \ ++ (amigaos_pack_cumulative_args(&(CUM))) + -+ return 1; -+} ++#undef TARGET_COMP_TYPE_ATTRIBUTES ++#define TARGET_COMP_TYPE_ATTRIBUTES amigaos_comp_type_attributes + -+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; -+ } ++/* end-GG-local */ + -+ if (!num_clobbers) -+ return pattern; ++#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) + -+ 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; -+ } ++/* { 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 }, + -+ 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); ++#define GOT_SYMBOL_NAME "" + -+ rtx pattern = add_clobbers (insn); ++#undef TARGET_RTX_COSTS ++#define TARGET_RTX_COSTS amigaos_rtx_costs ++bool ++amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool); + -+ 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) ++#undef TARGET_STRUCT_VALUE_RTX ++#define TARGET_STRUCT_VALUE_RTX amigaos_struct_value_rtx +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; -+} ++amigaos_struct_value_rtx(tree fntype, ++ int incoming ATTRIBUTE_UNUSED); ++ ++#undef TARGET_STATIC_CHAIN ++#define TARGET_STATIC_CHAIN amigaos_static_chain_rtx ++rtx ++amigaos_static_chain_rtx(const_tree fntype, ++ bool incoming 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))) ++ ++#undef TARGET_INSERT_ATTRIBUTES ++#define TARGET_INSERT_ATTRIBUTES amiga_insert_attribute + +void -+insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol) -+{ -+ rtx pattern = make_absolute2base (regno, base, with_symbol, true); ++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 @@ + - 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, " "); ++mregparm= ++Target RejectNegative Var(amigaos_regparm) Joined UInteger Init(-1) ++Pass arguments through registers. + -+ // 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::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; -+ } ++noixemul ++Target RejectNegative ++Do not use ixemul.library - use libnix instead to link + -+ 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))) ++ramiga-lib ++Target RejectNegative ++Use libinit.o as start file + -+ 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::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 fixups; - -- if (ii.in_proepi ()) -- continue; -+ // all paths to check -+ std::vector 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 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 fixups; -+ for (; pos < infos.size (); ++pos) -+ { -+ insn_info & jj = infos[pos]; - -- // all paths to check -- std::vector 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 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; -+ } ++ramiga-libr ++Target RejectNegative ++Use libinitr.o as start file + -+ // 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::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; ++ramiga-dev ++Target RejectNegative ++Use devinit.o as start file ++ ++msmall-code ++Target RejectNegative Var(flag_smallcode,1) ++small code model ++ ++fbaserel ++Target Report Var(flag_pic,3) ++data is addressed relative to a4 + -+ update_label2jump (); ++fbaserel32 ++Target Report Var(flag_pic,4) ++data is addressed relative to a4 with 32 bit offsets + -+ for (unsigned index = 0; index < infos.size (); ++index) -+ { -+ insn_info & ii = infos[index]; ++resident ++Target Common Report Var(flag_resident,3) ++data is addressed relative to a4, linked as resident + -+ 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::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 ()); ++resident32 ++Target Common Report Var(flag_resident,4) ++data is addressed relative to a4 with 32 bit offsets, linked as resident + -+ 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, '+'); ++mcrt= ++Target RejectNegative Var(amigaos_crt) Joined ++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 ++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. --// ++xx; --// printf ("x: %d\n", xx); --// if (xx <= 48 || xx > 54) --// do_autoinc = false; -- - if (be_very_verbose) - log ("ENTER\n"); + ;; This file is part of GCC. - -From 5c2dd1b12baffbf3e34da07e5fec09452f251d9e Mon Sep 17 00:00:00 2001 -From: bebbo -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 +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) ++{ ++ 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..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; - class track_var - { -+ unsigned * indexes; - rtx * values; - unsigned * versions; + #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 - 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); - } + #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 -- rtx * -- get_values () const -+ void -+ set (unsigned regno, unsigned index, rtx rtx, unsigned ver) - { -- return values; -+ if (regno >= FIRST_PSEUDO_REGISTER) -+ return; ++#ifdef TARGET_AMIGA ++#include "amigaos.h" ++#endif + -+ indexes[regno] = index; -+ values[regno] = rtx; -+ versions[regno] = ver; - } + 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 } + }; -- void -- set_version (unsigned regno, unsigned ver) -- { -- if (regno < FIRST_PSEUDO_REGISTER) -- versions[regno] = ver; -+ unsigned get_index(unsigned regno) const { -+ return indexes[regno]; -+ } +@@ -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." + -+ rtx get_value(unsigned regno) const { -+ return values[regno]; -+ } ++ This is not true at least for the AMIGA. ++ gcc 2.93 does not set the 68881 flag. + -+ unsigned get_version(unsigned regno) const { -+ return versions[regno]; - } ++ */ ++#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) - 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)); - } +@@ -545,7 +571,7 @@ m68k_option_override (void) + : (m68k_cpu_flags & FL_COLDFIRE) != 0 ? FPUTYPE_COLDFIRE + : FPUTYPE_68881); - /* 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; - } - } +- /* 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; - /* 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 - } + /* -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; - 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) +- 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; +- ++#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. */ +@@ -866,8 +896,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 +@@ -978,6 +1009,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) { -- rtx pattern = PATTERN(insn); -- rtx_insn * new_insn = make_insn_raw(pattern); -+ rtx pattern = PATTERN (insn); -+ rtx_insn * new_insn = make_insn_raw (pattern); +@@ -986,6 +1019,10 @@ m68k_expand_prologue (void) - // convert into POST_INC - rtx set0 = single_set (new_insn); -@@ -852,8 +855,8 @@ insn_info::make_post_inc (int regno) + m68k_compute_frame_layout (); - 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); ++#ifdef TARGET_AMIGA ++ amiga_emit_regparm_clobbers(); ++#endif ++ + if (flag_stack_usage_info) + current_function_static_stack_size + = current_frame.size + current_frame.offset; +@@ -1021,6 +1058,11 @@ m68k_expand_prologue (void) - 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)))) + 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) { - def |= use; -- use = u; -+ if ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG)) -+ use |= u; -+ else -+ use = u; - myuse = mu; + /* 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)); } - scan_rtx (SET_SRC(x)); -@@ -1439,7 +1446,7 @@ insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, b ++#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)); + } - 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; ++ /* 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)); ++ ++#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; } --/* 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 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]; ++#ifndef TARGET_AMIGA + /* On the m68k all args are always pushed. */ - // 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; + 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 - // 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) + /* 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)) { -- for (int regno = 0; regno < 16; ++regno) -- if ((1 << regno) & def) -- { -- values[regno] = 0; -- // invalidate all referring registers -- for (std::multimap::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; + 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 (!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::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)) + if (count == 2 && DATA_REG_P (operands[1]) + && next_insn_tests_no_inequality (insn)) { -- int regno = ii.get_dst_mem_regno (); -- values[regno] = 0; -- for (std::multimap::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); - } + 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; -- 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 (flag_pic ++ if (flag_pic && flag_pic < 3 + && !(strict_p && TARGET_PCREL) + && symbolic_operand (x, VOIDmode)) +- return false; ++ { ++ return false; ++ } -- 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 (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; -- 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; - } ++#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; + -+ // 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) ++ if (!amigaos_legitimate_src(x)) ++ return false; ++ ++#endif ++ + return m68k_decompose_address (mode, x, strict_p, &address); + } - std::vector 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) +@@ -2131,7 +2206,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 ++ ; + } - 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; - } + /* 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); -- if (jj.get_dst_addr () == size) -+ if (jj.get_src_mem_addr () == size) - match_size = true; ++// debug_rtx(pic_offset_table_rtx); ++ + crtl->uses_pic_offset_table = 1; - 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; - } + 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) ++ { ++ 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 ++ { ++ ++ /* SBF: Does the symbol use common or bss and qualifies for pic_reg? ++ * Do not ref to .text via pic_reg! ++ */ ++ 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) ++ { -- if (jj.get_dst_addr () == size) -+ if (jj.get_dst_mem_addr () == size) - match_size = true; +- 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); ++ ++ /* 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) + { +@@ -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); - fixups.insert (pos); - -From aa0ae94cf14aa246fb5f1907a086615e39278b3a Mon Sep 17 00:00:00 2001 -From: bebbo -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 - } +- 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) + } + } - 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; +-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; } -@@ -1439,7 +1443,7 @@ insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, b ++ + return false; + + case ASHIFT: +@@ -2931,6 +3045,25 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code, + *total = 0; + return false; - if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) && !has_dst_memreg () && get_dst_symbol () == with_symbol) ++ 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; + } +@@ -4456,7 +4589,9 @@ print_operand (FILE *file, rtx op, int letter) + else if (letter == 'p') { -- unsigned addr = get_dst_addr (); -+ unsigned addr = get_dst_mem_addr (); - unsigned offset = addr - base; - if (offset <= 0x7ffe) + 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) +@@ -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"); + } + else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode) + { + 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 + } + 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 (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); ++#else ++ asm_fprintf (file, "%I$%lx%08lx", l[0] & 0xFFFFFFFF, l[1] & 0xFFFFFFFF); ++#endif + } + else + { + /* 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) { -@@ -3883,7 +3887,7 @@ opt_absolute (void) - - std::vector 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 (flag_pic == 1 && TARGET_68020) + return "@GOT.w"; +@@ -4671,8 +4836,58 @@ print_operand_address (FILE *file, rtx addr) + { + struct m68k_address address; -- if (jj.get_dst_addr () == size) -+ if (jj.get_src_mem_addr () == size) - match_size = true; ++#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); ++ ++ 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 && 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 (); ++ } - fixups.insert (pos); + if (address.code == PRE_DEC) + fprintf (file, MOTOROLA ? "-(%s)" : "%s@-", +@@ -4714,6 +4929,14 @@ print_operand_address (FILE *file, rtx addr) } - 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 -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); + else + output_addr_const (file, addr); + -+ // if sp is used as source, we cannot shrink the stack yet -+ // too complicated -+ if (ii.get_src_regno() == STACK_POINTER_REGNUM) -+ return -1; ++#ifdef TARGET_AMIGA ++ if (SYMBOL_REF_FUNCTION_P(addr)) ++ { ++ if (flag_smallcode) ++ asm_fprintf(file, ":w(pc)"); ++ } ++#endif + } } + else +@@ -5155,7 +5378,9 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, - // add entry point - -From 0ef223ac20734c9b1998f62b6bef5f04d9cbf789 Mon Sep 17 00:00:00 2001 -From: bebbo -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 + /* 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. ++ */ - 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 -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) + 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)) { - 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; + 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) + { + 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 - // 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; + regno = true_regnum (x); -- 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, '+'); +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 */ - if (be_very_verbose) - log ("ENTER\n"); - -From 3d8120f2ca2cedeba1b42ece6e7c75f216324614 Mon Sep 17 00:00:00 2001 -From: bebbo -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 + /* Set the default. */ ++#ifndef TARGET_AMIGAOS_VASM + #define INT_OP_GROUP INT_OP_DOT_WORD ++#else ++#define INT_OP_GROUP INT_OP_DC ++#endif - 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 -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; + /* 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\ + } -+ 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); - } +- + /* 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 (ii.is_call ()) -@@ -3740,18 +3745,6 @@ track_regs () - if (!set || !ii.get_def ()) - continue; + #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" } -- // 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; +@@ -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 () \ - -From a8cd5ab8084d61d5d7ca31a840a737d4cf689022 Mon Sep 17 00:00:00 2001 -From: bebbo -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)]); + #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]))) -- emit_insn_after (newinsn, reg2x); -- - SET_INSN_DELETED(x2reg); - SET_INSN_DELETED(reg2x); - SET_INSN_DELETED(insn); + #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]))) -+ insn = emit_insn_after (pattern, reg2x); -+ insn_invalid_p (insn, 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) + - ++change_count; - } - } - -From 0521364bbbcab54adfecf35c42cfec87ddeceb69 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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) - } - } ++#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 + ++ + /* Control the assembler format that we output. */ -- if (code == CLOBBER) -- def |= use; -+ if (code == POST_INC || code == PRE_DEC || code == CLOBBER) -+ def |= myuse; - } ++#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 - void -@@ -3704,9 +3704,6 @@ track_regs () - ii.mark_visited (); - ii.get_track_var ()->assign (track); + #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) \ -- if (ii.is_compare ()) -- continue; + /* 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) - - 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); - } +-#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.is_compare ()) -+ continue; -+ - if (ii.is_call ()) - continue; + /* 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) \ + + #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 -@@ -3799,7 +3799,7 @@ opt_elim_dead_assign (int blocked_regno) - if (!set) - continue; ++#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 -- 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 -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); + #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 *); --/* 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 + #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 c9ea341789f4..71a54cededeb 100644 +index ec37bd76f55f..05ef02027f01 100644 --- gcc/config/m68k/m68k.md +++ gcc/config/m68k/m68k.md -@@ -1566,7 +1566,7 @@ +@@ -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) + ]) +@@ -1566,7 +1564,7 @@ + ;; 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" "=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")]) - +@@ -7204,6 +7202,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 +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))] + { diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h -index 7dc0e57f5cdc..cd099997bf07 100644 ---- gcc/config/m68k/m68kamigaos.h +new file mode 100644 +index 000000000000..3f3aafc5f254 +--- /dev/null +++ gcc/config/m68k/m68kamigaos.h -@@ -755,3 +755,13 @@ 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 \ -+ ) - -From 6f8c5e9a1995a1fbb15272251bfb15019486c053 Mon Sep 17 00:00:00 2001 -From: bebbo -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 -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); +@@ -0,0 +1,760 @@ ++/* m68kelf support, derived from m68kv4.h */ + -+ 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 (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); - } - - rtx pattern = add_clobbers (insn); -@@ -4019,7 +4037,7 @@ opt_absolute (void) - static int - try_auto_inc (unsigned index, insn_info & ii, rtx reg) - { -- 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 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; ++/* Target definitions for GNU compiler for mc680x0 running AmigaOs ++ Copyright (C) 1991-2016 Free Software Foundation, Inc. ++ ++ Written by Ron Guilmette (rfg@netcom.com) and Fred Fish (fnf@cygnus.com). ++ ++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 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. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#ifndef TARGET_AMIGA ++#define TARGET_AMIGA 1 ++#endif ++ ++#define HAS_INIT_SECTION ++ ++#ifndef SWBEG_ASM_OP ++#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" ++ ++#undef ASM_STABN_OP ++#define ASM_STABN_OP "|\t.stabn\t" ++#endif ++ ++#undef PIC_REG ++#define PIC_REG 12 ++ ++#undef FRAME_POINTER_REGNUM ++#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)]) ++ ++ ++ ++/* 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. */ ++ ++/* 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 */ ++ ++#undef REGISTER_PREFIX ++#define REGISTER_PREFIX "" ++ ++/* The prefix for local (compiler generated) labels. ++ 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. */ ++ ++#undef USER_LABEL_PREFIX ++#define USER_LABEL_PREFIX "_" ++ ++/* 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; ++ ++#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) ++ ++#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 ++ ++/* 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. */ ++ ++#undef M68K_STRUCT_VALUE_REGNUM ++#define M68K_STRUCT_VALUE_REGNUM A0_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) -+ 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; ++/* The static chain regnum defaults to a0, but we use that for ++ structure return, so have to use a1 for the static chain. */ + -+ fixups.insert (pos); ++#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" + - // 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 -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 -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(); ++#ifndef TARGET_AMIGAOS_VASM ++#define ASM_COMMENT_START "|" ++#else ++#define ASM_COMMENT_START "|" ++#endif + -+// 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()); ++/* 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. */ + - 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 -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 -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); - } -- return decl_attributes (node, attributes, flags); ++#undef DBX_REGISTER_NUMBER ++#define DBX_REGISTER_NUMBER(REGNO) (REGNO) + -+ tree returned_attrs = decl_attributes (node, attributes, flags); ++#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 + -+#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 * 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) -+ { -+ tree asmid = get_identifier("asmregs"); -+ tree syntheticid = get_identifier(synthetic); -+ tree newattr = tree_cons(asmid, syntheticid, NULL_TREE); ++#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 + -+ TYPE_ATTRIBUTES(TREE_TYPE(*node)) = chainon(newattr, TYPE_ATTRIBUTES(TREE_TYPE(*node))); -+ } -+ } ++#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 + -+ 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); ++/* 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 + -+ tree asm1 = lookup_attribute("asmregs", attrs1); -+ tree stack1 = lookup_attribute("stkparm", attrs1); -+ tree reg1 = lookup_attribute("regparm", attrs1); ++/* 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 */ + -+ tree attrs2 = TYPE_ATTRIBUTES(type2); ++#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 + -+ tree asm2 = lookup_attribute("asmregs", attrs2); -+ tree stack2 = lookup_attribute("stkparm", attrs2); -+ tree reg2 = lookup_attribute("regparm", attrs2); ++#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 + -+ 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; ++#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 + -+ 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 (reg2) -+ { -+ if (stack1 || asm1) -+ return 0; ++/* Specs, switches. */ + -+ int no2 = TREE_INT_CST_LOW(TREE_VALUE(reg2)); -+ return amigaos_regparm == no2; -+ } ++/* 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'. */ + -+ if (stack1) { -+ if (stack2) -+ return 1; -+ return amigaos_regparm == 0; -+ } ++#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) ++ ++#if 0 ++if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \ ++ builtin_define ("errno=(*ixemul_errno)"); \ ++ ++#endif ++ ++/* 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)) ++ ++// see 930623-1.c ++// ((N) == D0_REG || (N) == A0_REG || (TARGET_68881 && (N) == FP0_REG)) + -+ if (stack2) -+ return amigaos_regparm == 0; ++/* Inform the program which CPU we compile for. */ + -+ if (asm1) -+ { -+ if (!asm2) -+ 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) ++*/ + -+ return 0 == strcmp(IDENTIFIER_POINTER(TREE_VALUE(asm1)), IDENTIFIER_POINTER(TREE_VALUE(asm2))); - } -- if (arg1 || arg2) -- return 0; /* different count of parameters. */ ++/* 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" + -+ if (asm2) -+ return 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. */ + - } - 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 -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 -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 -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 -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); - } ++#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)}}" + -+namespace -+{ ++/* Various -m flags require special flags to the assembler. */ + -+ 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 */ -+ }; ++#undef ASM_SPEC ++#ifndef TARGET_AMIGAOS_VASM ++#define ASM_SPEC \ ++ "%(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}" ++#endif + -+ 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) -+ { -+ } ++#undef ASM_CPU_SPEC ++#define ASM_CPU_SPEC \ ++ "%{mcpu=*:-m%*} " \ ++ "%{m68000|mc68000:-m68010} " \ ++ "%{m6802*|mc68020:-m68020} " \ ++ "%{m68030} " \ ++ "%{m68040} " \ ++ "%{m68060}" + -+ /* opt_pass methods: */ -+ virtual bool -+ gate (function *) -+ { -+ return TARGET_AMIGA && flag_pic >= 3; -+ } ++#ifndef TARGET_AMIGAOS_VASM ++#define ASM_CPU_DEFAULT_SPEC \ ++ "%{!m680*:%{!mc680*:%{!mcpu=*:-m68000}}}" ++#else ++#define ASM_CPU_DEFAULT_SPEC \ ++ "%{!m680*:%{!mc680*:-m68000}}" ++#endif + -+ virtual unsigned int -+ execute (function *) -+ { -+ return execute_bbb_baserel (); -+ } ++/* 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. */ + -+ opt_pass * -+ clone () -+ { -+ pass_bbb_baserel * bbb = new pass_bbb_baserel (m_ctxt); -+ return bbb; -+ } ++#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}}}}" \ ++ ")" ++ ++#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)} " \ ++ "%{!noixemul:%{!mcrt*:%(startfile_libnix)}}" ++#endif + -+ unsigned int pp; ++#define ENDFILE_IXEMUL_SPEC "" ++#define ENDFILE_LIBNIX_SPEC "-lstubs" ++#define ENDFILE_CLIB2_SPEC "" + -+ unsigned -+ execute_bbb_baserel (void); -+ }; -+// class pass_bbb_optimizations ++#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)}}" + -+ /* 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; ++/* 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. */ + -+ rtx * src = &SET_SRC(set); -+ if (MEM_P(*src)) -+ src = &XEXP(*src, 0); ++#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}" + -+ 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); ++#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)} " \ ++ "%{!noixemul:%{!mcrt*:%(lib_libnix)}}" ++#endif + -+ // unlink PLUS/MINUS -+ *src = XEXP(*src, 0); ++#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)}}" + -+ 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))); ++/* 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. */ + -+ ispicref = true; -+ } -+ } -+ else -+ ispicref = CONST_PLUS_PIC_REG_CONST_UNSPEC_P(*src); ++#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 (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); ++/* 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. */ + -+ rtx pat0 = gen_rtx_SET(reg, *src); -+ rtx_insn * n0 = emit_insn_before(pat0, insn); ++#ifdef TARGET_AMIGAOS_VASM ++#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}} " \ ++ "%{mcpu=68020:-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}" ++#else ++#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 + -+ rtx pat1 = gen_rtx_SET(dest, reg); -+ rtx_insn * n1 = emit_insn_before(pat1, insn); ++/* Translate '-resident' to '-fbaserel' (they differ in linking stage only). ++ Don't put function addresses in registers for PC-relative code. */ + -+ SET_INSN_DELETED(insn); -+ } -+ } -+ } -+ } ++#define CC1_SPEC \ ++ "%{resident:-fbaserel} " \ ++ "%{resident32:-fbaserel32} " \ ++ "%{msmall-code:-fno-function-cse}" + -+ return 0; -+ } ++#define LINK_CPU_SPEC \ ++ "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \ ++ "%{m68881:-fl libm881}" + -+} // anon namespace ++/* [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. */ + -+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; -+ } ++#ifdef TARGET_AMIGAOS_VASM ++#define LINK_COMMAND_SPEC \ ++ "%{!fsyntax-only:" \ ++ "%{!c:" \ ++ "%{!M:" \ ++ "%{!MM:" \ ++ "%{!E:" \ ++ "%{!S:" \ ++ "%(linker) -Cvbcc %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*} }}}}}} " ++#else ++#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 + - /* 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; ++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 ++ 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. + - 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 -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 -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 -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 -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 -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 -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; - } - --/* -- * 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") ) -+ (const_int 0 [0]) -+ ] 6) ++ 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} + -+(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") ) -+ (const_int 0 [0]) -+ ] 6) -+ (const_int 1234 [0xe00]))))))) xyz.c:41 465 {*lea} ++/* begin-GG-local: dynamic libraries */ + - */ - 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) -+ { -+ rtx op = XEXP(src, 0); -+ if (GET_CODE(op) == MINUS || GET_CODE(op) == PLUS) -+ { -+ rtx x = XEXP(op, 0); -+ if (GET_CODE(x) == NOT || GET_CODE(x) == NEG) -+ { -+ 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; -+ } -+ } ++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 (GET_CODE(op) == UNSPEC) -+ { -+// debug_rtx(src); -+ return false; -+ } -+ } - -- x = XEXP(x, 0); -- return !REG_P(x); -+ return true; - } ++/* This macro is used to check if all collect2 facilities should be used. ++ We need a few special ones, like stripping after linking. */ + -+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); -+} ++#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). */ + -+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); -+ } -+ } -+ } ++#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG) + -+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 -+ } ++/* 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. */ + -+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 -+ } ++#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG) + -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); ++/* This macro is called at collect2 exit, to clean everything up. */ + -+extern bool -+amigaos_legitimate_src (rtx src); ++#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup + -+extern void -+amigaos_restore_a4 (void); ++/* 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. */ + -+extern void -+amigaos_alternate_frame_setup_f (int fsize); ++#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \ ++amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP)) + -+extern void -+amigaos_alternate_frame_setup (int fsize); ++/* 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 */ + -+#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND ++#undef MAX_OFILE_ALIGNMENT ++#define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT) + -+#define ALTERNATE_FRAME_SETUP_F(FSIZE) \ -+ (amigaos_alternate_frame_setup_f ((FSIZE))) ++#undef FIXED_INCLUDE_DIR ++#define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../include" + -+#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND ++// this disables tree_loop_distribute_patterns ++#define C_COMMON_OVERRIDE_OPTIONS flag_no_builtin = 1 ++/* Baserel support. */ + -+#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)); ++extern int amiga_is_const_pic_ref(const_rtx x); + -+#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 - - 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 -+ ; - } - - /* Return true if X matches the 'Q' constraint. It must be a memory - -From 06f886edaaf71078005b5a79e727c279eb3249ab Mon Sep 17 00:00:00 2001 -From: bebbo -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); ++#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 \ ++ )) + - 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 -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 -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 -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::iterator k = fixups.begin (); k != fixups.end (); ++k) - -From 73e0e6c763bd79928606dece20538b1a65a53683 Mon Sep 17 00:00:00 2001 -From: fautomat -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 -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; - - if (i0.get_dst_regno () != i1.get_src_regno ()) - -From d1a50a4116660763379610abfa3e150f1db1e874 Mon Sep 17 00:00:00 2001 -From: fautomat -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 -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; - } - - 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 -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 -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 -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 -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); - - rtx pat1 = gen_rtx_SET(dest, reg); -- rtx_insn * n1 = emit_insn_before(pat1, insn); -+ //rtx_insn * n1 = -+ emit_insn_before(pat1, insn); - - 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 ; - } - -+#define AMIGA_CHIP_SECTION_NAME ".datachip" ++/* Given that symbolic_operand(X), return TRUE if no special ++ base relative relocation is necessary */ + -+void -+amiga_insert_attribute (tree decl, tree * attr) -+{ -+ if (!*attr) -+ return; ++#undef LEGITIMATE_PIC_OPERAND_P ++#define LEGITIMATE_PIC_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))) || ++ ++#undef TARGET_GCC_EXCEPT_TABLE ++#define TARGET_GCC_EXCEPT_TABLE ".text" ++ ++#undef TARGET_GCC_EXCEPT_TABLE_S ++#define TARGET_GCC_EXCEPT_TABLE_S ".text" + -+ tree name = TREE_PURPOSE(*attr); ++#define EH_TABLES_CAN_BE_READ_ONLY 1 + -+ 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)); -+ } -+} ++/* 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 + - 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); ++/* The default number of data, address and float registers to use when ++ user specified '-mregparm' switch, not '-mregparm=' option. */ ++#undef AMIGAOS_DEFAULT_REGPARM ++#define AMIGAOS_DEFAULT_REGPARM 2 + -+ /** handled in print_operand_address(...) */ - if (CONST_PLUS_PIC_REG_CONST_UNSPEC_P(x)) -- { -- amigaos_add_offset_to_symbol(&src); - return true; -- } ++/* 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); ++ ++//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 - return amigaos_legitimate_src(x) && amigaos_legitimate_src(XEXP(src, 1)); - } -@@ -868,28 +918,6 @@ amigaos_legitimate_src (rtx src) - return true; - } + /* Target OS builtins. */ ++#ifndef TARGET_OS_CPP_BUILTINS + #define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("__embedded__"); \ + } \ + while (0) ++#endif --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); + /* 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. */ - #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 + /* 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 - if (!m68k_decompose_address (QImode, addr, true, &address)) -- gcc_unreachable (); -+ { -+ debug_rtx(addr); -+ gcc_unreachable (); -+ } - 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) - } +-__inline extern double ++__inline double + sin (double x) + { + double value; +@@ -75,7 +75,7 @@ sin (double x) + return value; } -+ - /* Execute PASS. */ +-__inline extern double ++__inline double + cos (double x) + { + double value; +@@ -86,7 +86,7 @@ cos (double x) + return value; + } - bool -@@ -2299,7 +2301,8 @@ execute_one_pass (opt_pass *pass) +-__inline extern double ++__inline double + tan (double x) + { + double value; +@@ -97,7 +97,7 @@ tan (double x) + return value; + } - bool gate_status; +-__inline extern double ++__inline double + asin (double x) + { + double value; +@@ -108,7 +108,7 @@ asin (double x) + return value; + } --// dump_insns(pass->name); -+ if (string_bbb_opts && strchr (string_bbb_opts, 'Y')) -+ dump_insns(pass->name); +-__inline extern double ++__inline double + acos (double x) + { + double value; +@@ -119,7 +119,7 @@ acos (double x) + return value; + } - /* 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 -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 -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 +-__inline extern double ++__inline double + atan (double x) + { + double value; +@@ -130,7 +130,7 @@ atan (double x) + return value; + } - /* 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); +-__inline extern double ++__inline double + atan2 (double y, double x) + { + double pi, pi_over_2; +@@ -187,7 +187,7 @@ atan2 (double y, double x) } - 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]; +-__inline extern double ++__inline double + sinh (double x) + { + double value; +@@ -198,7 +198,7 @@ sinh (double x) + return value; + } -- 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; +-__inline extern double ++__inline double + cosh (double x) + { + double value; +@@ -209,7 +209,7 @@ cosh (double x) + return value; + } - rtx_insn * insn = ii.get_insn (); -@@ -2751,10 +2751,10 @@ opt_commute_add_move (void) - if (!MEM_P(dst)) - continue; +-__inline extern double ++__inline double + tanh (double x) + { + double value; +@@ -220,7 +220,7 @@ tanh (double x) + return value; + } -- 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); +-__inline extern double ++__inline double + atanh (double x) + { + double value; +@@ -231,7 +231,7 @@ atanh (double x) + return value; + } -- 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 ())); +-__inline extern double ++__inline double + exp (double x) + { + double value; +@@ -242,7 +242,7 @@ exp (double x) + return value; + } - 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) +-__inline extern double ++__inline double + expm1 (double x) + { + double value; +@@ -253,7 +253,7 @@ expm1 (double x) + return value; + } - insn = emit_insn_before (newinsn, next); +-__inline extern double ++__inline double + log (double x) + { + double value; +@@ -264,7 +264,7 @@ log (double x) + return value; + } -- add_reg_note (next, REG_INC, ii.get_dst_reg()); -+ add_reg_note (next, REG_INC, ii.get_dst_reg ()); +-__inline extern double ++__inline double + log1p (double x) + { + double value; +@@ -275,7 +275,7 @@ log1p (double x) + return value; + } - ++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; +-__inline extern double ++__inline double + log10 (double x) + { + double value; +@@ -286,7 +286,7 @@ log10 (double x) + return value; + } -@@ -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; +-__inline extern double ++__inline double + sqrt (double x) + { + double value; +@@ -297,13 +297,13 @@ sqrt (double x) + return value; + } -@@ -4172,7 +4178,7 @@ try_auto_inc (unsigned index, insn_info & ii, rtx reg) - if (!ii.make_post_inc (regno)) - return 0; +-__inline extern double ++__inline double + hypot (double x, double y) + { + return sqrt (x*x + y*y); + } -- 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 ()); +-__inline extern double ++__inline double + pow (double x, double y) + { + if (x > 0) +@@ -352,7 +352,7 @@ pow (double x, double y) + } + } - // fix all offsets / adds - for (std::set::iterator k = fixups.begin (); k != fixups.end (); ++k) -@@ -4220,13 +4226,12 @@ opt_autoinc () - // if ((ii.get_myuse () & 0xff0000)) - // continue; +-__inline extern double ++__inline double + fabs (double x) + { + double value; +@@ -363,7 +363,7 @@ fabs (double x) + return value; + } -- 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 ()); +-__inline extern double ++__inline double + ceil (double x) + { + int rounding_mode, round_up; +@@ -385,7 +385,7 @@ ceil (double x) + return value; + } -- 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 ()); +-__inline extern double ++__inline double + floor (double x) + { + int rounding_mode, round_down; +@@ -408,7 +408,7 @@ floor (double x) + return value; + } - } -@@ -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); +-__inline extern double ++__inline double + rint (double x) + { + int rounding_mode, round_nearest; +@@ -430,7 +430,7 @@ rint (double x) + return value; + } - rtx pat0 = gen_rtx_SET(reg, *src); - //rtx_insn * n0 = -- emit_insn_before(pat0, insn); -+ emit_insn_before (pat0, insn); +-__inline extern double ++__inline double + fmod (double x, double y) + { + double value; +@@ -442,7 +442,7 @@ fmod (double x, double y) + return value; + } - rtx pat1 = gen_rtx_SET(dest, reg); - //rtx_insn * n1 = -- emit_insn_before(pat1, insn); -+ emit_insn_before (pat1, insn); +-__inline extern double ++__inline double + drem (double x, double y) + { + double value; +@@ -454,7 +454,7 @@ drem (double x, double y) + return value; + } - SET_INSN_DELETED(insn); - } - -From 34ff5f41808c0f6eef3ea36cb6592f696b568e0f Mon Sep 17 00:00:00 2001 -From: fautomat -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 -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) +-__inline extern double ++__inline double + scalb (double x, int n) + { + double value; +@@ -466,7 +466,7 @@ scalb (double x, int n) + return value; + } - // convert into POST_INC - rtx set0 = single_set (new_insn); -+ if (!set0) -+ return false; -+ - rtx set = set0; +-__inline extern double ++__inline double + logb (double x) + { + double exponent; +@@ -477,7 +477,7 @@ logb (double x) + return exponent; + } - if (is_compare ()) - -From d565753800ac3d71d6367a3c5f7db440b2068e48 Mon Sep 17 00:00:00 2001 -From: fautomat -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 -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 -+#include -+#include +-__inline extern double ++__inline double + ldexp (double x, int n) + { + double value; +@@ -489,7 +489,7 @@ ldexp (double x, int n) + return value; + } - int be_very_verbose; - bool be_verbose; +-__inline extern double ++__inline double + frexp (double x, int *exp) + { + double float_exponent; +@@ -514,7 +514,7 @@ frexp (double x, int *exp) + return mantissa; + } - extern struct lang_hooks lang_hooks; +-__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); + }) -+static void -+update_insn_infos (void); -+static unsigned -+track_regs (); +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. ++ ++# 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) ++ ++# 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 ++ ++### 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 ++ $(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 +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 ++ ++# 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 + - /* 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]; ++# 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 + -+ 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; ++# Arrange for guides to be installed with GCC. + -+ 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; ++### begin-GG-local: gcc-amigaos ++#EXTRA_INSTALL_TARGETS = install-guide install-gcc-amigaos-doc ++### end-GG-local + -+ *mask |= mask[REGNO(x)]; -+ *z = value[REGNO(x)]; -+ return true; -+ } ++# Where the guide files go + -+ /* 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; ++guidedir = $(prefix)/guide + -+ 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; -+ } ++# Actually install guides. + -+ /* 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; ++installdirs-guide: ++ $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(guidedir) + -+ case REG: -+ if (!extend (&m, mask, dstMode, m)) -+ return false; ++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 + -+ *z = gen_rtx_MEM (GET_MODE(x), m); -+ return true; ++$(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 + -+ 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; ++### begin-GG-local: gcc-amigaos ++# Build and install gcc-amigaos.guide - documentation specific to the ++# AmigaOS port of GCC. + -+ if (REG_P(y)) -+ if (!extend (&y, mask, dstMode, y)) -+ return false; ++gcc-amigaos-doc:: doc/gcc-amigaos.info doc/gcc-amigaos.guide + -+ 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)); ++doc/gcc-amigaos.info doc/gcc-amigaos.guide: gcc-amigaos.texi + -+ *z = gen_rtx_MEM (GET_MODE(x), m); -+ return true; -+ } -+ } -+ return false; -+ } ++install-gcc-amigaos-doc: doc installdirs installdirs-guide \ ++ $(DESTDIR)$(infodir)/gcc-amigaos.info \ ++ $(DESTDIR)$(guidedir)/gcc-amigaos.guide ++### end-GG-local + -+ 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; -+ } -+ } ++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). + -+ rtx -+ get (unsigned regno) -+ { -+ if (regno >= FIRST_PSEUDO_REGISTER) -+ return 0; ++This file is part of GCC. + -+ 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; ++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 (x == 0 || value[regno] == 0) -+ return false; ++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 z = 0; -+ unsigned m = 0; -+ if (!extend (&z, &m, GET_MODE(x), x)) -+ return false; ++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. */ + -+ 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; ++#ifndef _FCNTL_H_ ++#include ++#endif + -+ 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); -+ } -+ } ++/* 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. */ + -+ 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; -+ } - } - } - -@@ -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 () - { -+ update_insn2index (); ++#define SYSTEM_INCLUDE_DIR "/gg/os-include" ++#define STANDARD_INCLUDE_DIR "/gg/include" + - 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; - } - -+bool dump_reg_track; -+void -+append_reg_cache (FILE * f, rtx_insn * insn) -+{ -+ i2i_iterator i = insn2info.find (insn); -+ if (i == insn2info.end ()) -+ return; ++#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/" + -+ insn_info & jj = *i->second; -+ unsigned index = jj.get_index (); -+ if (index + 1 < infos.size ()) -+ ++index; -+ insn_info & ii = infos[index]; ++/* The AmigaOS stores file names with regard to upper/lower case, but actions ++ on existing files are case independent on the standard filesystems. + -+ track_var * track = ii.get_track_var (); -+ if (track == 0) -+ return; ++ A good example of where this causes problems is the conflict between the C ++ include file and the C++ include file , where the C++ ++ include file dir is searched first and thus causes includes of ++ to include instead. + -+ fprintf (f, "\n"); ++ 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. */ + -+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) -+ { -+ rtx v = track->get (regno); -+ if (v == 0) -+ continue; ++#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE)) + -+// if (GET_CODE(v) == CONST_INT && GET_MODE(v) == VOIDmode) -+// continue; ++/* 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. */ + -+ fprintf (f, "%s=", reg_names[regno]); ++#define DIR_SEPARATOR '/' ++#define VOL_SEPARATOR ':' ++#define DIR_SEPARATOR_2 VOL_SEPARATOR + -+ print_inline_rtx (f, v, 12); -+ fprintf (f, "\n"); -+ } -+} ++/* Zap PREFIX_INCLUDE_DIR, since with the AmigaOS port it is the same as ++ STANDARD_INCLUDE_DIR. */ + - /* 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); ++#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; - 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); + /* 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 (ii.is_compare ()) - continue; + /* 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 (ii.is_call ()) -- continue; + 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++; ++ ++#ifdef TARGET_AMIGA ++ { ++ bool addglue = true; ++ /* do not add glue if exceptions are disabled. */ ++ for (int ii = 0; ii < argc; ++ii) + { -+ track->clear_aftercall (index); -+ continue; ++ if (decoded_options[ii].opt_index == OPT_fexceptions) ++ addglue = decoded_options[ii].value; + } - - 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 (); -+ } ++ 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 + - 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); + /* Add target-dependent static library, if necessary. */ + if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL) + { +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 (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) -+{ -+ 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; -+} ++ 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]; ++ } + - 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); -+ return r; - } + DF_REF_REGNO (the_ref) = new_regno; + DF_REF_REG (the_ref) = regno_reg_rtx[new_regno]; +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 */ + - /* 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; -+ } ++#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); + - 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; ++ 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 + } -- 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); + 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 (GET_CODE(src) == CONST) -@@ -903,16 +945,12 @@ amigaos_legitimate_src (rtx src) - if (!REG_P(reg)) - return true; + static GTY(()) int call_site_base; --// debug_rtx(src); - return false; +@@ -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; - if (GET_CODE(op) == UNSPEC) -- { --// debug_rtx(src); -- return false; -- } -+ return false; - } - - return true; -@@ -986,3 +1024,13 @@ amigaos_alternate_frame_setup (int fsize) + 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 - } - -+#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. + rtx_insn *next; ++ current_insn = insn; -@@ -97,12 +97,6 @@ - (match_test "!TARGET_PCREL") - (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)"))) + insn_counter++; --(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; +@@ -3622,6 +3624,12 @@ 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 *); + - if (!amigaos_legitimate_src(x)) - return false; ++ extern bool dump_reg_track; ++ void append_reg_cache (FILE * f, rtx_insn * insn); + - #endif + 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); + } - 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); ++ if (be_very_verbose) ++ append_reg_usage(asm_out_file, current_insn); ++ if (dump_reg_track) ++ append_reg_cache(asm_out_file, current_insn); + -+ x = &XEXP(*x, 1); // CONST -+ if (GET_CODE(*x) == CONST) -+ x = &XEXP(*x, 0); + /* 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; + ++ 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; + } + -+ /* if there is a plus - swap it. -+ * we want n+symbol:W (not symbol:W+n) -+ */ -+ if (GET_CODE(*x) == PLUS) ++#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) + { -+ 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)); ++ *p = 0; ++ p = strrchr(glp, '/'); ++ if (p) ++ { ++ *p = 0; ++ p = strrchr(glp, '/'); ++ if (p) ++ { ++ p[1] = 0; ++ p = concat(glp, "m68k-amigaos/", NULL); ++ } ++ } ++ } ++ free(glp); ++ } ++ if (!p) ++ p = concat("../../../../", "", NULL); + - 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))] ++ 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) { -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); + return optimize > 0 && flag_gcse + && !fun->calls_setjmp ++#ifndef TARGET_AMIGA + && optimize_function_for_speed_p (fun) ++#endif + && dbg_cnt (pre); + } --/* 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) +@@ -4118,6 +4120,9 @@ class pass_rtl_hoist : public rtl_opt_pass + bool + pass_rtl_hoist::gate (function *) { - 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) ++#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 + } - if (be_very_verbose) - append_reg_usage(asm_out_file, current_insn); -+ if (dump_reg_track) -+ append_reg_cache(asm_out_file, current_insn); + } // anon namespace +diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h +index d711530d0535..4f08f81a3ae0 100644 +--- gcc/ginclude/stddef.h ++++ gcc/ginclude/stddef.h +@@ -325,6 +325,7 @@ typedef __rune_t rune_t; + #define __WCHAR_TYPE__ int + #endif + #ifndef __cplusplus ++#define _WCHAR_T_ int + typedef __WCHAR_TYPE__ wchar_t; + #endif + #endif +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; + } - /* Write out the variable names for operands, if we know them. */ - if (flag_verbose_asm) + #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 b216ee028245..1d53bb23b1b0 100644 +index e89618111245..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 -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 -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 -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<assign (track); -+ if (ii.is_compare ()) ++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)) ++ { ++ rtx set= single_set (insn); ++ if (!set) + 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 -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; - -- 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<clear (dregno, index); -+ track->clear (ii.get_mode(), dregno, index); ++ if (amiga_is_const_pic_ref(SET_SRC(set)) && MEM_P(SET_DEST(set))) ++ debug_rtx(insn); ++ } ++#endif ++ } ++} ++ ++ + /* Execute PASS. */ - unsigned def = ii.get_def () & 0xffffff; - track->clear_for_mask (def, index); - -From dfad986c2f43b33e98dbc2b70a4058b8cf771a37 Mon Sep 17 00:00:00 2001 -From: bebbo -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; + bool +@@ -2278,6 +2301,9 @@ execute_one_pass (opt_pass *pass) -- 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< -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<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 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); - *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; + NEXT_PASS (pass_expand); ++ NEXT_PASS (pass_bbb_baserel); - 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; + 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; ++ + if (RTX_FRAME_RELATED_P (old_insn)) + { + 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 (REG_P(y)) -@@ -261,6 +260,9 @@ class track_var - if (regno >= FIRST_PSEUDO_REGISTER) - return; + /* 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 (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; + /* 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 ++ 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; -- value[regno] = gen_rtx_raw_CONST_INT (mode, 0x100000000000000LL | ((long long int) (regno) << 32) | index); -- mask[regno] = 1<clear (ii.get_mode(), dregno, index); -+ track->clear (ii.get_mode (), dregno, index); +- /* 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; +- ++ + n_succs_used++; - 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); + 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]); + } - if (ispicref) - { - -From b9eb7c80c772836b151ec2ae333c15d1ea744e18 Mon Sep 17 00:00:00 2001 -From: fautomat -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 -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); - } +@@ -954,7 +955,7 @@ regrename_analyze (bitmap bb_mask) + numbering in its subpatterns. */ -@@ -4118,6 +4120,9 @@ class pass_rtl_hoist : public rtl_opt_pass bool - pass_rtl_hoist::gate (function *) +-regrename_do_replace (struct du_head *head, int reg) ++regrename_do_replace (struct du_head *head, int regno) { -+#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 -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 -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) + struct du_chain *chain; + unsigned int base_regno = head->regno; +@@ -962,19 +963,20 @@ regrename_do_replace (struct du_head *head, int reg) - if (src_op && get_src_mem_regno () == regno) + for (chain = head->first; chain; chain = chain->next_use) { -- if (src_op == NEG || src_op == NOT) -+ if (src_op == NEG || src_op == NOT || src_op == SIGN_EXTEND) - mem = XEXP(mem, 0); +- 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 - 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 -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 -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; +- 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; -+#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 +- 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]; + - /* 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 ++ /* 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); ++ ++ 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; + } + +@@ -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 *) { - -From 8a91b7265bab01a1011c8f153323732d9eee48cf Mon Sep 17 00:00:00 2001 -From: bebbo -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 +- return (optimize > 0 && (flag_rename_registers)); ++ return (optimize > 0 && (flag_rename_registers) && !TARGET_AMIGA); + } - /* 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 -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 -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(-) - + 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" ++ ++#ifndef TARGET_GCC_EXCEPT_TABLE ++#define TARGET_GCC_EXCEPT_TABLE ".gcc_except_table" ++#endif ++ ++#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 @@ -41512,1452 +10347,745 @@ index b65f29c13a46..8ead5ec3fcbb 100644 + 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 -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" -+#else -+#define DATA_SECTION_ASM_OP "\tsection\tdata" -+#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 -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 -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 -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 > & 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 > & 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 positions; -- std::vector > locs; -- std::vector > patch; -- bool ok = true; -- -- for (std::set::iterator i = found.begin (); ok && i != found.end (); ++i) -+ for (std::set::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 >::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 >::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 -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 -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; - } + 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 *); --__inline extern double -+__inline double - asin (double x) - { - double value; -@@ -108,7 +108,7 @@ asin (double x) - return value; - } + static _cpp_buff *new_buff (size_t); --__inline extern double -+__inline double - acos (double x) - { - double value; -@@ -119,7 +119,7 @@ acos (double x) - return value; - } ++/* ++ * SBF: This flag is set if an asm statement is parsed, to support multiline strings in __asm() ++ */ ++int in_assembler_directive; --__inline extern double -+__inline double - atan (double x) - { - double value; -@@ -130,7 +130,7 @@ atan (double x) - return value; - } + /* Utility routine: --__inline extern double -+__inline double - atan2 (double y, double x) - { - double pi, pi_over_2; -@@ -187,7 +187,7 @@ atan2 (double y, double x) +@@ -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); ++ } } } --__inline extern double -+__inline double - sinh (double x) - { - double value; -@@ -198,7 +198,7 @@ sinh (double x) - return value; - } +@@ -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) ++ { ++ 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; ++ } + 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 ++++ libgcc/Makefile.in +@@ -230,7 +230,7 @@ endif + # Options to use when compiling libgcc2.a. + # + LIBGCC2_DEBUG_CFLAGS = -g +-LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ ++LIBGCC2_CFLAGS = $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ + $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \ + -fbuilding-libgcc -fno-stack-protector \ + $(INHIBIT_LIBC_CFLAGS) +@@ -284,7 +284,7 @@ INTERNAL_CFLAGS = $(CFLAGS) $(LIBGCC2_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ + $(INCLUDES) @set_have_cc_tls@ @set_use_emutls@ --__inline extern double -+__inline double - cosh (double x) - { - double value; -@@ -209,7 +209,7 @@ cosh (double x) - return value; - } + # Options to use when compiling crtbegin/end. +-CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ ++CRTSTUFF_CFLAGS = $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \ + $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \ + -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 6f6810cf0baf..7117e7983b53 100644 +--- libgcc/config.host ++++ libgcc/config.host +@@ -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-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" + ;; +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/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c +index fe41edf26aa0..90926104d8fd 100644 +--- libgcc/config/m68k/fpgnulib.c ++++ libgcc/config/m68k/fpgnulib.c +@@ -105,6 +105,7 @@ union long_double_long + + #ifndef EXTFLOAT --__inline extern double -+__inline double - tanh (double x) ++#ifdef __UNORDSF2 + int + __unordsf2(float a, float b) { - double value; -@@ -220,7 +220,7 @@ tanh (double x) - return value; +@@ -118,7 +119,9 @@ __unordsf2(float a, float b) + return 1; + return 0; } ++#endif --__inline extern double -+__inline double - atanh (double x) ++#ifdef __UNORDDF2 + int + __unorddf2(double a, double b) { - double value; -@@ -231,7 +231,7 @@ atanh (double x) - return value; +@@ -134,7 +137,9 @@ __unorddf2(double a, double b) + return 1; + return 0; } ++#endif --__inline extern double -+__inline double - exp (double x) - { - double value; -@@ -242,7 +242,7 @@ exp (double x) - return value; - } ++#ifdef __FLOATUNSIDF + /* convert unsigned int to double */ + double + __floatunsidf (unsigned long a1) +@@ -167,7 +172,9 @@ __floatunsidf (unsigned long a1) --__inline extern double -+__inline double - expm1 (double x) - { - double value; -@@ -253,7 +253,7 @@ expm1 (double x) - return value; + return dl.d; } ++#endif --__inline extern double -+__inline double - log (double x) - { - double value; -@@ -264,7 +264,7 @@ log (double x) - return value; - } ++#ifdef __FLOATSIDF + /* convert int to double */ + double + __floatsidf (long a1) +@@ -213,7 +220,9 @@ __floatsidf (long a1) --__inline extern double -+__inline double - log1p (double x) - { - double value; -@@ -275,7 +275,7 @@ log1p (double x) - return value; + return dl.d; } ++#endif --__inline extern double -+__inline double - log10 (double x) - { - double value; -@@ -286,7 +286,7 @@ log10 (double x) - return value; ++#ifdef __FLOATUNSISF + /* convert unsigned int to float */ + float + __floatunsisf (unsigned long l) +@@ -221,7 +230,10 @@ __floatunsisf (unsigned long l) + double foo = __floatunsidf (l); + return foo; } ++#endif --__inline extern double -+__inline double - sqrt (double x) - { - double value; -@@ -297,13 +297,13 @@ sqrt (double x) - return value; ++ ++#ifdef __FLOATSISF + /* convert int to float */ + float + __floatsisf (long l) +@@ -229,7 +241,10 @@ __floatsisf (long l) + double foo = __floatsidf (l); + return foo; } ++#endif ++ --__inline extern double -+__inline double - hypot (double x, double y) - { - return sqrt (x*x + y*y); ++#ifdef __EXTENDSFDF2 + /* convert float to double */ + double + __extendsfdf2 (float a1) +@@ -268,7 +283,9 @@ __extendsfdf2 (float a1) + + return dl.d; } ++#endif --__inline extern double -+__inline double - pow (double x, double y) - { - if (x > 0) -@@ -352,7 +352,7 @@ pow (double x, double y) - } ++#ifdef __TRUNCDFSF2 + /* convert double to float */ + float + __truncdfsf2 (double a1) +@@ -336,7 +353,9 @@ __truncdfsf2 (double a1) + fl.l = PACK (SIGND (dl1), exp, mant); + return (fl.f); } ++#endif --__inline extern double -+__inline double - fabs (double x) - { - double value; -@@ -363,7 +363,7 @@ fabs (double x) - return value; ++#ifdef __FIXDFSI + /* convert double to int */ + long + __fixdfsi (double a1) +@@ -368,7 +387,9 @@ __fixdfsi (double a1) + + return (SIGND (dl1) ? -l : l); } ++#endif --__inline extern double -+__inline double - ceil (double x) - { - int rounding_mode, round_up; -@@ -385,7 +385,7 @@ ceil (double x) - return value; ++#ifdef __FIXSFSI + /* convert float to int */ + long + __fixsfsi (float a1) +@@ -376,6 +397,7 @@ __fixsfsi (float a1) + double foo = a1; + return __fixdfsi (foo); } ++#endif + + #else /* EXTFLOAT */ --__inline extern double -+__inline double - floor (double x) +@@ -396,6 +418,8 @@ float __truncdfsf2 (double); + long __fixdfsi (double); + long __fixsfsi (float); + ++#if !defined(EXTFLOATCMP) ++ + int + __unordxf2(long double a, long double b) { - int rounding_mode, round_down; -@@ -408,7 +408,7 @@ floor (double x) - return value; +@@ -445,38 +469,6 @@ __extenddfxf2 (double d) + return ldl.ld; } --__inline extern double -+__inline double - rint (double x) - { - int rounding_mode, round_nearest; -@@ -430,7 +430,7 @@ rint (double x) - return value; +-/* convert long double to double */ +-double +-__truncxfdf2 (long double ld) +-{ +- register long exp; +- register union double_long dl; +- register union long_double_long ldl; +- +- ldl.ld = ld; +- /*printf ("xfdf in: %s\n", dumpxf (ld));*/ +- +- dl.l.upper = SIGNX (ldl); +- if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle && !ldl.l.lower) +- { +- dl.l.lower = 0; +- return dl.d; +- } +- +- exp = EXPX (ldl) - EXCESSX + EXCESSD; +- /* ??? quick and dirty: keep `exp' sane */ +- if (exp >= EXPDMASK) +- exp = EXPDMASK - 1; +- dl.l.upper |= exp << (32 - (EXPDBITS + 1)); +- /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */ +- dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1); +- dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1)); +- dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1); +- +- /*printf ("xfdf out: %g\n", dl.d);*/ +- return dl.d; +-} +- + /* convert a float to a long double */ + long double + __extendsfxf2 (float f) +@@ -549,6 +541,8 @@ __negxf2 (long double x1) + return - (double) x1; } --__inline extern double -+__inline double - fmod (double x, double y) ++#else ++ + long + __cmpxf2 (long double x1, long double x2) { - double value; -@@ -442,7 +442,7 @@ fmod (double x, double y) - return value; +@@ -591,5 +585,38 @@ __gexf2 (long double x1, long double x2) + return __cmpdf2 ((double) x1, (double) x2); } --__inline extern double -+__inline double - drem (double x, double y) - { - double value; -@@ -454,7 +454,7 @@ drem (double x, double y) - return value; ++/* convert long double to double */ ++double ++__truncxfdf2 (long double ld) ++{ ++ register long exp; ++ register union double_long dl; ++ register union long_double_long ldl; ++ ++ ldl.ld = ld; ++ /*printf ("xfdf in: %s\n", dumpxf (ld));*/ ++ ++ dl.l.upper = SIGNX (ldl); ++ if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle && !ldl.l.lower) ++ { ++ dl.l.lower = 0; ++ return dl.d; ++ } ++ ++ exp = EXPX (ldl) - EXCESSX + EXCESSD; ++ /* ??? quick and dirty: keep `exp' sane */ ++ if (exp >= EXPDMASK) ++ exp = EXPDMASK - 1; ++ dl.l.upper |= exp << (32 - (EXPDBITS + 1)); ++ /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */ ++ dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1); ++ dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1)); ++ dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1); ++ ++ /*printf ("xfdf out: %g\n", dl.d);*/ ++ return dl.d; ++} ++#endif /* EXTFLOATCMP */ ++ + #endif /* !__mcoldfire__ */ + #endif /* EXTFLOAT */ +diff --git a/libgcc/config/m68k/t-floatlib b/libgcc/config/m68k/t-floatlib +index 1ee8782d9fd2..2365433a59b3 100644 +--- libgcc/config/m68k/t-floatlib ++++ libgcc/config/m68k/t-floatlib +@@ -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 = $(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 ++ ++xfpgnulib__unorddf2.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __UNORDDF2' > xfpgnulib__unorddf2.c ++ cat $< >> xfpgnulib__unorddf2.c ++ ++xfpgnulib__floatunsidf.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __FLOATUNSIDF' > xfpgnulib__floatunsidf.c ++ cat $< >> xfpgnulib__floatunsidf.c ++ ++xfpgnulib__floatsidf.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __FLOATSIDF' > xfpgnulib__floatsidf.c ++ cat $< >> xfpgnulib__floatsidf.c ++ ++xfpgnulib__floatunsisf.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __FLOATUNSISF' > xfpgnulib__floatunsisf.c ++ cat $< >> xfpgnulib__floatunsisf.c ++ ++xfpgnulib__floatsisf.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __FLOATSISF' > xfpgnulib__floatsisf.c ++ cat $< >> xfpgnulib__floatsisf.c ++ ++xfpgnulib__extendsfdf2.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __EXTENDSFDF2' > xfpgnulib__extendsfdf2.c ++ cat $< >> xfpgnulib__extendsfdf2.c ++ ++xfpgnulib__truncdfsf2.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __TRUNCDFSF2' > xfpgnulib__truncdfsf2.c ++ cat $< >> xfpgnulib__truncdfsf2.c ++ ++xfpgnulib__fixdfsi.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __FIXDFSI' > xfpgnulib__fixdfsi.c ++ cat $< >> xfpgnulib__fixdfsi.c ++ ++xfpgnulib__fixsfsi.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define __FIXSFSI' > xfpgnulib__fixsfsi.c ++ cat $< >> xfpgnulib__fixsfsi.c ++ ++xfpgnulib.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define EXTFLOAT' > xfpgnulib.c ++ cat $< >> xfpgnulib.c ++ ++xfpgnulib__cmpxf2.c: $(srcdir)/config/m68k/fpgnulib.c ++ echo '#define EXTFLOAT' > xfpgnulib__cmpxf2.c ++ echo '#define EXTFLOATCMP' >> xfpgnulib__cmpxf2.c ++ cat $< >> xfpgnulib__cmpxf2.c ++ +\ No newline at end of file +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 ++ ++EXTRA_PARTS=cxxglue.o ++ +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) } --__inline extern double -+__inline double - scalb (double x, int n) - { - double value; -@@ -466,7 +466,7 @@ scalb (double x, int n) - return value; - } + /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */ ++#ifdef TARGET_AMIGA ++static int overregs[16]; ++#endif --__inline extern double -+__inline double - logb (double x) - { - double exponent; -@@ -477,7 +477,7 @@ logb (double x) - return exponent; - } + 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]; --__inline extern double -+__inline double - ldexp (double x, int n) - { - double value; -@@ -489,7 +489,7 @@ ldexp (double x, int n) - return value; - } ++#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) --__inline extern double -+__inline double - frexp (double x, int *exp) - { - double float_exponent; -@@ -514,7 +514,7 @@ frexp (double x, int *exp) - return mantissa; - } + ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index]; --__inline extern double -+__inline double - modf (double x, double *ip) ++ 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) { - double temp; - -From 443179daa5f06a569a4de7e62c431d787c066f86 Mon Sep 17 00:00:00 2001 -From: fautomat -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 -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 -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)); + 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]); + } ++#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 **)¤t) - 1); ++ /* search the movem -x(a5),regs insn.*/ ++ for (;;) + { -+ bool r = memory_address_addr_space_p (mode, addr, as); -+ if (!r) debug_rtx(addr); -+ gcc_assert (r); ++ unsigned short s = *sp++; ++// printf("%04x ", s); ++ gcc_assert(s != (unsigned short)0x4e75);// hit return? ouch! ++ if (s == (unsigned short)0x4ced) ++ break; + } - else - addr = memory_address_addr_space (mode, addr, as); - } - -From 765a8c42eee2c949fc5d31b3e4693c8237bdb48b Mon Sep 17 00:00:00 2001 -From: bebbo -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; ++ 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]; -- if (flag_pic -+ if (flag_pic && flag_pic < 3 - && !(strict_p && TARGET_PCREL) - && symbolic_operand (x, VOIDmode)) -- return false; ++ /* 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) + { -+ return false; ++ 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; - if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P && reach > 1) - { - -From 44cf4734135f00e7949a431a308e5da436735300 Mon Sep 17 00:00:00 2001 -From: bebbo -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 +- uw_install_context (&this_context, &cur_context); ++ uw_install_context (&this_context, &cur_context, 0); + } -@@ -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 -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 -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; - } - } -+ 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<value[i])) - { - value[i] = o->value[i] = 0; -- mask[i] = mask[i] = 0; -+ mask[i] = 0; - } - } - } -@@ -3940,7 +3965,10 @@ track_regs () - continue; +@@ -208,7 +208,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, + if (code != _URC_INSTALL_CONTEXT) + return code; - if (dregno < 0) -- continue; -+ { -+ track->invalidate_mem(SET_DEST(set)); -+ continue; -+ } +- uw_install_context (&this_context, &cur_context); ++ uw_install_context (&this_context, &cur_context, 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 -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; - } -- - 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<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 -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 (); +- uw_install_context (&this_context, &cur_context); ++ uw_install_context (&this_context, &cur_context, 2); + } -+ /* 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 -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 - } - } -- 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 - } - } +@@ -258,7 +258,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc) -- - 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 (); + gcc_assert (code == _URC_INSTALL_CONTEXT); - /* 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 (); +- uw_install_context (&this_context, &cur_context); ++ uw_install_context (&this_context, &cur_context, 3); + } - /* 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); +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 - positions.push_back (*i); - } -@@ -3945,11 +3945,17 @@ track_regs () - if (ii.is_compare ()) - continue; + 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]); ++ } ++#endif ++ return r; ++} +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 -- 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); + #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; + } - if (ii.is_call ()) - { -@@ -3980,7 +3986,7 @@ track_regs () ++#ifdef __AMIGA__ ++ ctype::~ctype() ++ { ++ _S_destroy_c_locale(_M_c_locale_ctype); ++ if (_M_del) ++ delete[] this->table(); ++ } ++#endif ++ + char + ctype::do_toupper(char __c) const + { +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) - { -- track->invalidate_mem(SET_DEST(set)); -+ 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 -@@ -4031,7 +4037,7 @@ opt_elim_dead_assign (int blocked_regno) + #pragma GCC system_header +- ++#ifdef AMIGA ++#include ++#endif + #include - // 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 (); + // 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 -@@ -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 } + const size_t ctype::table_size; -+#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\ -+} ++#ifndef __AMIGA__ ++/* moved to ctype_configure_char */ + ctype::~ctype() + { + _S_destroy_c_locale(_M_c_locale_ctype); + if (_M_del) + delete[] this->table(); + } +#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 -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 -- cgit v1.2.3