diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/Makefile.in | 3 | ||||
-rw-r--r-- | gcc/config/sparc/t-linux64 | 3 | ||||
-rw-r--r-- | gcc/gcc.c | 189 | ||||
-rw-r--r-- | gcc/genmultilib | 57 |
5 files changed, 233 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5428664..82f31b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +1999-12-16 Ben Collins <bcollins@debian.org> + + * Makefile.in: Pass a new MULTILIB_EXCLUSIONS option as the sixth + argument to genmultilib. + * genmultilib: accept new MULTILIB_EXCLUSIONS option and output + the contents into the multilib.h header. + * gcc.c: Declare multilib_exclusions for the specs file. + (set_multilib_dir): Use it. + (print_multilib_info): Likewise. + * t-linux64: Declare arguments for new MULTILIB_EXCLUSIONS option + to pass to genmultilib. + 2000-03-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * builtins.c (built_in_class_names, built_in_names): Constify a diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 17f67b5..7817ed1 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1182,7 +1182,8 @@ s-mlib: $(srcdir)/genmultilib Makefile "$(MULTILIB_DIRNAMES)" \ "$(MULTILIB_MATCHES)" \ "$(MULTILIB_EXCEPTIONS)" \ - "$(MULTILIB_EXTRA_OPTS)" > tmp-mlib.h + "$(MULTILIB_EXTRA_OPTS)" \ + "$(MULTILIB_EXCLUSIONS)" > tmp-mlib.h $(SHELL) $(srcdir)/move-if-change tmp-mlib.h multilib.h touch s-mlib diff --git a/gcc/config/sparc/t-linux64 b/gcc/config/sparc/t-linux64 index efabfc7..bf81219 100644 --- a/gcc/config/sparc/t-linux64 +++ b/gcc/config/sparc/t-linux64 @@ -1,7 +1,8 @@ MULTILIB_OPTIONS = m64/m32 mno-app-regs|mcmodel=medany MULTILIB_DIRNAMES = 64 32 alt MULTILIB_MATCHES = mcmodel?medany=mcmodel?medmid -MULTILIB_EXCEPTIONS = *m32/*medany *m32/*mno-app-regs +MULTILIB_EXCEPTIONS = m32/mno-app-regs* m32/mcmodel=* +MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib @@ -511,6 +511,7 @@ static struct obstack multilib_obstack; static char *multilib_select; static char *multilib_matches; static char *multilib_defaults; +static char *multilib_exclusions; #include "multilib.h" /* Check whether a particular argument is a default argument. */ @@ -1143,6 +1144,7 @@ static struct spec_list static_specs[] = { INIT_STATIC_SPEC ("multilib_defaults", &multilib_defaults), INIT_STATIC_SPEC ("multilib_extra", &multilib_extra), INIT_STATIC_SPEC ("multilib_matches", &multilib_matches), + INIT_STATIC_SPEC ("multilib_exclusions", &multilib_exclusions), INIT_STATIC_SPEC ("linker", &linker_name_spec), }; @@ -5083,6 +5085,13 @@ main (argc, argv) obstack_1grow (&multilib_obstack, 0); multilib_matches = obstack_finish (&multilib_obstack); + q = multilib_exclusions_raw; + while ((p = *q++) != (char *) 0) + obstack_grow (&multilib_obstack, p, strlen (p)); + + obstack_1grow (&multilib_obstack, 0); + multilib_exclusions = obstack_finish (&multilib_obstack); + need_space = FALSE; for (i = 0; i < sizeof (multilib_defaults_raw) / sizeof (multilib_defaults_raw[0]); @@ -5929,23 +5938,82 @@ default_arg (p, len) return 0; } -/* Work out the subdirectory to use based on the - options. The format of multilib_select is a list of elements. - Each element is a subdirectory name followed by a list of options - followed by a semicolon. gcc will consider each line in turn. If - none of the options beginning with an exclamation point are - present, and all of the other options are present, that - subdirectory will be used. */ +/* Work out the subdirectory to use based on the options. The format of + multilib_select is a list of elements. Each element is a subdirectory + name followed by a list of options followed by a semicolon. The format + of multilib_exclusions is the same, but without the preceding + directory. First gcc will check the exclusions, if none of the options + beginning with an exclamation point are present, and all of the other + options are present, then we will ignore this completely. Passing + that, gcc will consider each multilib_select in turn using the same + rules for matching the options. If a match is found, that subdirectory + will be used. */ static void set_multilib_dir () { - char *p = multilib_select; + char *p; int this_path_len; char *this_path, *this_arg; int not_arg; int ok; + p = multilib_exclusions; + while (*p != '\0') + { + /* Ignore newlines. */ + if (*p == '\n') + { + ++p; + continue; + } + + /* Check the arguments. */ + ok = 1; + while (*p != ';') + { + if (*p == '\0') + abort (); + + if (! ok) + { + ++p; + continue; + } + + this_arg = p; + while (*p != ' ' && *p != ';') + { + if (*p == '\0') + abort (); + ++p; + } + + if (*this_arg != '!') + not_arg = 0; + else + { + not_arg = 1; + ++this_arg; + } + + ok = used_arg (this_arg, p - this_arg); + if (not_arg) + ok = ! ok; + + if (*p == ' ') + ++p; + } + + if (ok) + { + return; + } + + ++p; + } + + p = multilib_select; while (*p != '\0') { /* Ignore newlines. */ @@ -6037,7 +6105,8 @@ set_multilib_dir () matches. The options are print without a leading dash. There are no spaces to make it easy to use the information in the shell. Each subdirectory is printed only once. This assumes the ordering - generated by the genmultilib script. */ + generated by the genmultilib script. Also, we leave out ones that match + the exclusions. */ static void print_multilib_info () @@ -6049,6 +6118,7 @@ print_multilib_info () while (*p != '\0') { + skip = 0; /* Ignore newlines. */ if (*p == '\n') { @@ -6065,12 +6135,103 @@ print_multilib_info () ++p; } - /* If this is a duplicate, skip it. */ - skip = (last_path != 0 && p - this_path == last_path_len - && ! strncmp (last_path, this_path, last_path_len)); + /* Check for matches with the multilib_exclusions. We don't bother + with the '!' in either list. If any of the exclusion rules match + all of its options with the select rule, we skip it. */ + { + char *e = multilib_exclusions; + char *this_arg; + + while (*e != '\0') + { + int m = 1; + /* Ignore newlines. */ + if (*e == '\n') + { + ++e; + continue; + } + + /* Check the arguments. */ + while (*e != ';') + { + char *q; + int mp = 0; + + if (*e == '\0') + abort (); + + if (! m) + { + ++e; + continue; + } + + this_arg = e; + + while (*e != ' ' && *e != ';') + { + if (*e == '\0') + abort (); + ++e; + } + + q = p + 1; + while (*q != ';') + { + char *arg; + int len = e - this_arg; + + if (*q == '\0') + abort (); + + arg = q; + + while (*q != ' ' && *q != ';') + { + if (*q == '\0') + abort (); + ++q; + } - last_path = this_path; - last_path_len = p - this_path; + if (! strncmp(arg, this_arg, (len < q - arg) ? q - arg : len) || + default_arg(this_arg, e - this_arg)) + { + mp = 1; + break; + } + + if (*q == ' ') + ++q; + + } + + if (! mp) + m = 0; + + if (*e == ' ') + ++e; + } + if (m) + { + skip = 1; + break; + } + + if (*e != '\0') + ++e; + } + } + + if (! skip) + { + /* If this is a duplicate, skip it. */ + skip = (last_path != 0 && p - this_path == last_path_len + && ! strncmp (last_path, this_path, last_path_len)); + + last_path = this_path; + last_path_len = p - this_path; + } /* If this directory requires any default arguments, we can skip it. We will already have printed a directory identical to diff --git a/gcc/genmultilib b/gcc/genmultilib index b6dfdf3..6610b7b 100644 --- a/gcc/genmultilib +++ b/gcc/genmultilib @@ -53,6 +53,16 @@ # The optional fifth argument is a list of options that should be # used whenever building multilib libraries. +# The optional sixth argument is a list of exclusions used internally by +# the compiler similar to exceptions. The difference being that exclusions +# allow matching default options that genmultilib does not know about and +# is done at runtime as opposed to being sorted out at compile time. +# Each element in the list is a seperate exclusion rule. Each rule is +# a list of options (sans preceding '-') seperated by a '/'. The options +# on the rule are grouped as an AND operation, and all options much match +# for the rule to exclude a set. Options can be preceded with a '!' to +# match a logical NOT. + # The output looks like # #define MULTILIB_MATCHES "\ # SUBDIRECTORY OPTIONS;\ @@ -66,23 +76,28 @@ # The order of the subdirectories is such that they can be created in # order; that is, a subdirectory is preceded by all its parents. -# Here is a example (this is simplified from the actual 680x0 case): -# genmultilib "m68000/m68020 msoft-float" "m68000 m68020 msoft-float" -# "m68000=mc68000" +# Here is an example (this is from the actual sparc64 case): +# genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt' +# 'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*' +# 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany' # This produces: -# ". !m68000 !mc68000 !m68020 !msoft-float;", -# "m68000 m68000 !m68020 !msoft-float;", -# "m68000 mc60000 !m68020 !msoft-float;", -# "m68020 !m68000 !mc68000 m68020 !msoft-float;", -# "msoft-float !m68000 !mc68000 !m68020 msoft-float;", -# "m68000/msoft-float m68000 !m68020 msoft-float;", -# "m68000/msoft-float mc68000 !m68020 msoft-float;", -# "m68020/msoft-float !m68000 !mc68000 m68020 msoft-float;", +# ". !m64 !m32 !mno-app-regs !mcmodel=medany;", +# "64 m64 !m32 !mno-app-regs !mcmodel=medany;", +# "32 !m64 m32 !mno-app-regs !mcmodel=medany;", +# "alt !m64 !m32 mno-app-regs mcmodel=medany;", +# "alt !m64 !m32 mno-app-regs !mcmodel=medany;", +# "alt !m64 !m32 !mno-app-regs mcmodel=medany;", +# "64/alt m64 !m32 mno-app-regs mcmodel=medany;", +# "64/alt m64 !m32 mno-app-regs !mcmodel=medany;", +# "64/alt m64 !m32 !mno-app-regs mcmodel=medany;", # -# The effect is that `gcc -msoft-float' (for example) will append -# msoft-float to the directory name when searching for libraries or -# startup files, and `gcc -m68000 -msoft-float' (for example) will -# append m68000/msoft-float. +# The effect is that `gcc -mno-app-regs' (for example) will append "alt" +# to the directory name when searching for libraries or startup files and +# `gcc -m32 -mcmodel=medany' (for example) will append "32/alt". Also note +# that exclusion above is moot, unless the compiler had a default of -m32, +# which would mean that all of the "alt" directories (not the 64/alt ones) +# would be ignored (not generated, nor used) since the exclusion also +# matches the multilib_default args. # Copy the positional parameters into variables. options=$1 @@ -90,6 +105,7 @@ dirnames=$2 matches=$3 exceptions=$4 extra=$5 +exclusions=$6 echo "static char *multilib_raw[] = {" @@ -286,6 +302,17 @@ echo "};" # Output the default options now echo "" echo "static char *multilib_extra = \"${extra}\";" + +# Output the exclusion rules now +echo "" +echo "static char *multilib_exclusions_raw[] = {" +for rule in ${exclusions}; do + s=`echo ${rule} | sed -e 's,/, ,g'` + echo "\"${s};\"," +done +echo "NULL" +echo "};" + rm -f tmpmultilib2 exit 0 |