This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: new option for genmultilibs to have runtime exclusions


This was aimed at a more general way to handle the strange setup that
sparc64 requires. Basically it needed to know somethings at compile (with
the current setup) that wasn't available until runtime (the
multilib_defaults) for the exceptions that genmultilib needed to parse out.

This patch allows a new sixth argument to genmultilibs called
MULTILIB_EXCLUSIONS. These are basically like exceptions, but are checked
at runtime instead of at the time of the multilib.h generations (without
wildcard matches though). This allows checking against default args. So with
this layout we get this for sparc64-linux:

multilib.h:

	static char *multilib_raw[] = {
	". !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;",
	NULL
	};

	static char *multilib_matches_raw[] = {
	"mcmodel=medmid mcmodel=medany;",
	"m64 m64;",
	"m32 m32;",
	"mno-app-regs mno-app-regs;",
	"mcmodel=medany mcmodel=medany;",
	NULL
	};

	static char *multilib_extra = "";

	static char *multilib_exclusions_raw[] = {
	"m32 !m64 mno-app-regs;",
	"m32 !m64 mcmodel=medany;",
	NULL
	};

Once compiled, we get this for --print-multi-lib on m64 default compiles:

	.;
	alt;@mno-app-regs@mcmodel=medany
	32;@m32

And this for m32 default compiles:

	.;
	64;@m64
	64/alt;@m64@mno-app-regs@mcmodel=medany

Which is the way it is supposed to be (Jakub, confirm?). I'm hoping that
this general solution will serve to help other archs (haven't checked
yet).

Note, I changed the example in genmultilib to match the one from
sparc64-linux since it uses more of the options (including this one).

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.


-- 
 -----------=======-=-======-=========-----------=====------------=-=------
/  Ben Collins  --  ...on that fantastic voyage...  --  Debian GNU/Linux   \
`     bcollins@debian.org  -  collinbm@djj.state.va.us  -  bmc@visi.net    '
 `---=========------=======-------------=-=-----=-===-======-------=--=---'
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.349
diff -u -r1.349 Makefile.in
--- Makefile.in	1999/12/16 17:50:28	1.349
+++ Makefile.in	1999/12/16 22:58:26
@@ -1170,7 +1170,8 @@
 	  "$(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
 
Index: genmultilib
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genmultilib,v
retrieving revision 1.4
diff -u -r1.4 genmultilib
--- genmultilib	1999/12/09 10:41:44	1.4
+++ genmultilib	1999/12/16 22:58:28
@@ -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 @@
 matches=$3
 exceptions=$4
 extra=$5
+exclusions=$6
 
 echo "static char *multilib_raw[] = {"
 
@@ -286,6 +302,17 @@
 # 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
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcc.c,v
retrieving revision 1.122
diff -u -r1.122 gcc.c
--- gcc.c	1999/12/14 16:05:23	1.122
+++ gcc.c	1999/12/16 22:58:44
@@ -521,6 +521,7 @@
 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.  */
@@ -1154,6 +1155,7 @@
   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),
 };
 
@@ -5033,6 +5035,13 @@
     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]);
@@ -5893,27 +5902,86 @@
   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.  */
+      if (*p == '\n')
 	{
 	  ++p;
 	  continue;
@@ -6001,7 +6069,8 @@
    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 ()
@@ -6013,6 +6082,7 @@
 
   while (*p != '\0')
     {
+      skip = 0;
       /* Ignore newlines.  */
       if (*p == '\n')
 	{
@@ -6028,13 +6098,104 @@
 	    abort ();
 	  ++p;
 	}
+
+      /* 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;
+			}
+
+		      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 this is a duplicate, skip it.  */
-      skip = (last_path != 0 && p - this_path == last_path_len
-	      && ! strncmp (last_path, this_path, last_path_len));
+      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;
+          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
Index: config/sparc/t-linux64
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sparc/t-linux64,v
retrieving revision 1.3
diff -u -r1.3 t-linux64
--- t-linux64	1999/12/09 10:41:45	1.3
+++ t-linux64	1999/12/16 22:58:44
@@ -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

PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]