[avr,applied] Fix PR107201 -nodevicelib not working for all devices.

Message ID 238c0c70-5c89-483f-9387-1c6f1b4db6b2@gjlay.de
State Accepted
Headers
Series [avr,applied] Fix PR107201 -nodevicelib not working for all devices. |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Georg-Johann Lay Jan. 12, 2024, 12:51 p.m. UTC
  Since the advent of devices AVR*, the spec pattern mmcu=avr* does no
more work to discriminate between devices and cores like avr51.

This means -nodevicelib no more works for AVR* devices because that
option is removed for mmcu=avr* (which were only cores in the old days).

Instead of that pattern, a new spec function is used.

When there are no objections or improvements within the next week or
so, I'd install the patch below.

Johann

--

AVR: target/107201: Make -nodevicelib work for all devices.

	The driver-avr.cc contains a spec that discriminates between cores
	and devices by means of a mmcu=avr* spec pattern.  This does not
	work for new devices like AVR128* which also start with mmcu=avr
	like all cores do.  The patch uses a new spec function in order to
	tell apart cores from devices.

gcc/
	PR target/107201
	* config/avr/avr.h (EXTRA_SPEC_FUNCTIONS): Add no-devlib, avr_no_devlib.
	* config/avr/driver-avr.cc (avr_no_devlib): New function.
	(avr_devicespecs_file): Use it to remove -nodevicelib from the
	options for cores only.
	* config/avr/avr-arch.h (avr_get_parch): New prototype.
	* config/avr/avr-devices.cc (avr_get_parch): New function.
  

Patch

diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h
index 03b3263d529..0ee335038a4 100644
--- a/gcc/config/avr/avr-arch.h
+++ b/gcc/config/avr/avr-arch.h
@@ -195,6 +195,7 @@  typedef struct
 
 extern const avr_arch_t avr_arch_types[];
 extern const avr_arch_t *avr_arch;
+extern const avr_arch_t *avr_get_parch (const char *mcu);
 
 extern const avr_mcu_t avr_mcu_types[];
 
diff --git a/gcc/config/avr/avr-devices.cc b/gcc/config/avr/avr-devices.cc
index 90846f3da21..43d38eb3916 100644
--- a/gcc/config/avr/avr-devices.cc
+++ b/gcc/config/avr/avr-devices.cc
@@ -153,4 +153,20 @@  avr_inform_core_architectures (void)
   free (archs);
 }
 
+
+/* When MCU names a core arch like "avr5", then return a pointer to the
+   respective entry in avr_arch_types[].  Otherwise, return NULL.  */
+
+const avr_arch_t *
+avr_get_parch (const char *mcu)
+{
+  for (size_t i = 0; i < ARRAY_SIZE (avr_arch_types); ++i)
+    {
+      if (strcmp (mcu, avr_arch_types[i].name) == 0)
+	return & avr_arch_types[i];
+    }
+
+  return NULL;
+}
+
 #endif // IN_GEN_AVR_MMCU_TEXI
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 3ef60b9ab7f..7f7e23183b2 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -500,9 +500,11 @@  typedef struct avr_args
 
 extern const char *avr_devicespecs_file (int, const char**);
 extern const char *avr_double_lib (int, const char**);
+extern const char *avr_no_devlib (int, const char**);
 
 #define EXTRA_SPEC_FUNCTIONS                            \
   { "double-lib", avr_double_lib },                     \
+  { "no-devlib", avr_no_devlib },                       \
   { "device-specs-file", avr_devicespecs_file },
 
 /* Driver self specs has lmited functionality w.r.t. '%s' for dynamic specs.
diff --git a/gcc/config/avr/driver-avr.cc b/gcc/config/avr/driver-avr.cc
index 2512c2c546a..b44136e2577 100644
--- a/gcc/config/avr/driver-avr.cc
+++ b/gcc/config/avr/driver-avr.cc
@@ -105,7 +105,12 @@  avr_devicespecs_file (int argc, const char **argv)
   return concat ("%{!nodevicespecs:-specs=device-specs", dir_separator_str,
 				 "specs-", mmcu, "%s} %<nodevicespecs"
 #if defined (WITH_AVRLIBC)
-                 " %{mmcu=avr*:" X_NODEVLIB "} %{!mmcu=*:" X_NODEVLIB "}",
+		 // Return X_NODEVLIB when we are compiling for a core.  As
+		 // there are devices like AVR128DA32, a simple mmcu=avr* to
+		 // discriminate between cores and devices ceased to work,
+		 // hence use spec function no-devlib=avr_no_devlib from below.
+		 // See also PR107201.
+		 " %{mmcu=avr*:%:no-devlib(avr%*)} %{!mmcu=*:" X_NODEVLIB "}",
 #else
                  " " X_NODEVLIB,
 #endif
@@ -113,6 +118,22 @@  avr_devicespecs_file (int argc, const char **argv)
 }
 
 
+/* Return X_NODEVLIB when ARGV[] contains a core like "avr5",
+   otherwise return "".  */
+
+const char*
+avr_no_devlib (int argc, const char **argv)
+{
+  for (int i = 0; i < argc; ++i)
+    {
+      if (avr_get_parch (argv[i]))
+	return X_NODEVLIB;
+    }
+
+  return "";
+}
+
+
 /* Re-build the -mdouble= and -mlong-double= options.  This is needed
    because these options are not independent of each other.  */