Commit 80b38f83 by Georg-Johann Lay Committed by Georg-Johann Lay

Add support for AVR devices from the 0-series.

	PR target/92545
	* config/avr/avr-arch.h (avr_mcu_t) <flash_pm_offset>: New field.
	* config/avr/avr-devices.c (avr_mcu_types): Adjust initializers.
	* config/avr/avr-mcus.def (AVR_MCU): Add respective field.
	* config/avr/specs.h (LINK_SPEC) <%(link_pm_base_address)>: Add.
	* config/avr/gen-avr-mmcu-specs.c (print_mcu)
	<*cpp, *cpp_mcu, *cpp_avrlibc, *link_pm_base_address>: Emit code
	for spec definitions.
	* doc/avr-mmcu.texi: Regenerate.

From-SVN: r278387
parent 586bbef1
2019-11-18 Georg-Johann Lay <avr@gjlay.de>
Add support for AVR devices from the 0-series.
PR target/92545
* config/avr/avr-arch.h (avr_mcu_t) <flash_pm_offset>: New field.
* config/avr/avr-devices.c (avr_mcu_types): Adjust initializers.
* config/avr/avr-mcus.def (AVR_MCU): Add respective field.
* config/avr/specs.h (LINK_SPEC) <%(link_pm_base_address)>: Add.
* config/avr/gen-avr-mmcu-specs.c (print_mcu)
<*cpp, *cpp_mcu, *cpp_avrlibc, *link_pm_base_address>: Emit code
for spec definitions.
* doc/avr-mmcu.texi: Regenerate.
2019-11-18 Hongtao Liu <hongtao.liu@intel.com> 2019-11-18 Hongtao Liu <hongtao.liu@intel.com>
PR target/92448 PR target/92448
...@@ -126,6 +126,9 @@ typedef struct ...@@ -126,6 +126,9 @@ typedef struct
/* Flash size in bytes. */ /* Flash size in bytes. */
int flash_size; int flash_size;
/* Offset where flash is seen in the RAM address space. */
int flash_pm_offset;
} avr_mcu_t; } avr_mcu_t;
/* AVR device specific features. /* AVR device specific features.
......
...@@ -117,12 +117,12 @@ avr_texinfo[] = ...@@ -117,12 +117,12 @@ avr_texinfo[] =
const avr_mcu_t const avr_mcu_t
avr_mcu_types[] = avr_mcu_types[] =
{ {
#define AVR_MCU(NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, TEXT_SEC, FLASH_SIZE)\ #define AVR_MCU(NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, TEXT_SEC, FLASH_SIZE, PMOFF) \
{ NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, TEXT_SEC, FLASH_SIZE }, { NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, TEXT_SEC, FLASH_SIZE, PMOFF },
#include "avr-mcus.def" #include "avr-mcus.def"
#undef AVR_MCU #undef AVR_MCU
/* End of list. */ /* End of list. */
{ NULL, ARCH_UNKNOWN, AVR_ISA_NONE, NULL, 0, 0, 0 } { NULL, ARCH_UNKNOWN, AVR_ISA_NONE, NULL, 0, 0, 0, 0 }
}; };
......
...@@ -97,7 +97,7 @@ static const char help_dev_lib_name[] = ...@@ -97,7 +97,7 @@ static const char help_dev_lib_name[] =
"# #include <avr/io.h>\n" "# #include <avr/io.h>\n"
"#\n" "#\n"
"# will include the desired device header. For ATmega8A the supplement\n" "# will include the desired device header. For ATmega8A the supplement\n"
"# to *cpp would read\n" "# to *cpp_avrlibc would read\n"
"#\n" "#\n"
"# -D__AVR_DEV_LIB_NAME__=m8a\n" "# -D__AVR_DEV_LIB_NAME__=m8a\n"
"\n"; "\n";
...@@ -132,6 +132,14 @@ print_mcu (const avr_mcu_t *mcu) ...@@ -132,6 +132,14 @@ print_mcu (const avr_mcu_t *mcu)
bool rcall = (mcu->dev_attribute & AVR_ISA_RCALL); bool rcall = (mcu->dev_attribute & AVR_ISA_RCALL);
bool is_arch = mcu->macro == NULL; bool is_arch = mcu->macro == NULL;
bool is_device = ! is_arch; bool is_device = ! is_arch;
int flash_pm_offset = 0;
if (arch->flash_pm_offset
&& mcu->flash_pm_offset
&& mcu->flash_pm_offset != arch->flash_pm_offset)
{
flash_pm_offset = mcu->flash_pm_offset;
}
if (is_arch if (is_arch
&& (ARCH_AVR2 == arch_id && (ARCH_AVR2 == arch_id
...@@ -262,6 +270,14 @@ print_mcu (const avr_mcu_t *mcu) ...@@ -262,6 +270,14 @@ print_mcu (const avr_mcu_t *mcu)
fprintf (f, "\n\n"); fprintf (f, "\n\n");
} }
if (is_device
&& flash_pm_offset)
{
fprintf (f, "*link_pm_base_address:\n");
fprintf (f, "\t--defsym=__RODATA_PM_OFFSET=0x%x", flash_pm_offset);
fprintf (f, "\n\n");
}
// Specs known to GCC. // Specs known to GCC.
if (is_device) if (is_device)
...@@ -273,10 +289,26 @@ print_mcu (const avr_mcu_t *mcu) ...@@ -273,10 +289,26 @@ print_mcu (const avr_mcu_t *mcu)
#if defined (WITH_AVRLIBC) #if defined (WITH_AVRLIBC)
fprintf (f, "%s\n", help_dev_lib_name); fprintf (f, "%s\n", help_dev_lib_name);
fprintf (f, "*cpp_avrlibc:\n");
fprintf (f, "\t-D__AVR_DEVICE_NAME__=%s", mcu->name);
fprintf (f, "\n\n");
#endif // WITH_AVRLIBC #endif // WITH_AVRLIBC
fprintf (f, "*cpp_mcu:\n");
fprintf (f, "\t-D%s", mcu->macro);
if (flash_pm_offset)
{
fprintf (f, " -U__AVR_PM_BASE_ADDRESS__");
fprintf (f, " -D__AVR_PM_BASE_ADDRESS__=0x%x", flash_pm_offset);
}
fprintf (f, "\n\n");
fprintf (f, "*cpp:\n"); fprintf (f, "*cpp:\n");
fprintf (f, "\t-D%s -D__AVR_DEVICE_NAME__=%s", mcu->macro, mcu->name); fprintf (f, "\t%%(cpp_mcu)");
#if defined (WITH_AVRLIBC)
fprintf (f, " %%(cpp_avrlibc)");
#endif // WITH_AVRLIBC
fprintf (f, "\n\n"); fprintf (f, "\n\n");
} }
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include "avr-devices.c" #include "avr-devices.c"
static const char* static const avr_mcu_t*
mcu_name[sizeof avr_mcu_types / sizeof avr_mcu_types[0]]; mcus[sizeof avr_mcu_types / sizeof avr_mcu_types[0]];
static int letter (char c) static int letter (char c)
{ {
...@@ -39,21 +39,80 @@ static int digit (char c) ...@@ -39,21 +39,80 @@ static int digit (char c)
} }
static int static int
comparator (const void *va, const void *vb) str_prefix_p (const char *str, const char *prefix)
{ {
const char *a = *(const char* const*) va; return strncmp (str, prefix, strlen (prefix)) == 0;
const char *b = *(const char* const*) vb; }
while (*a && *b)
/* Used by string comparator to group MCUs by their
name prefix like "attiny" or "atmega". */
static int
c_prefix (const char *str)
{
static const char *const prefixes[] =
{
"attiny", "atmega", "atxmega", "ata", "at90"
};
int i, n = (int) (sizeof (prefixes) / sizeof (*prefixes));
for (i = 0; i < n; i++)
if (str_prefix_p (str, prefixes[i]))
return i;
return n;
}
/* If A starts a group of digits, return their value as a number. */
static int
c_number (const char *a)
{
int val = 0;
if (digit (*a) && ! digit (*(a-1)))
{ {
/* Make letters smaller than digits so that `atmega16a' follows while (digit (*a))
`atmega16' without `atmega161' etc. between them. */ val = 10 * val + (*a++) - '0';
}
return val;
}
if (letter (*a) && digit (*b)) /* Compare two MCUs and order them for easy lookup. */
return -1;
static int
comparator (const void *va, const void *vb)
{
const avr_mcu_t *mcu_a = *(const avr_mcu_t* const*) va;
const avr_mcu_t *mcu_b = *(const avr_mcu_t* const*) vb;
const char *a = mcu_a->name;
const char *b = mcu_b->name;
if (digit (*a) && letter (*b)) // First, group MCUs according to their pure-letter prefix.
return 1;
int c = c_prefix (a) - c_prefix (b);
if (c)
return c;
// Second, if their prefixes are the same, group according to
// their flash size.
c = (int) mcu_a->flash_size - (int) mcu_b->flash_size;
if (c)
return c;
// Third, group according to aligned groups of digits.
while (*a && *b)
{
c = c_number (a) - c_number (b);
if (c)
return c;
if (*a != *b) if (*a != *b)
return *a - *b; return *a - *b;
...@@ -74,20 +133,20 @@ print_mcus (size_t n_mcus) ...@@ -74,20 +133,20 @@ print_mcus (size_t n_mcus)
if (!n_mcus) if (!n_mcus)
return; return;
qsort (mcu_name, n_mcus, sizeof (char*), comparator); qsort (mcus, n_mcus, sizeof (avr_mcu_t*), comparator);
printf ("@*@var{mcu}@tie{}="); printf ("@*@var{mcu}@tie{}=");
for (i = 0; i < n_mcus; i++) for (i = 0; i < n_mcus; i++)
{ {
printf (" @code{%s}%s", mcu_name[i], i == n_mcus-1 ? ".\n\n" : ","); printf (" @code{%s}%s", mcus[i]->name, i == n_mcus-1 ? ".\n\n" : ",");
if (i && !strcmp (mcu_name[i], mcu_name[i-1])) if (i && !strcmp (mcus[i]->name, mcus[i-1]->name))
{ {
/* Sanity-check: Fail on devices that are present more than once. */ // Sanity-check: Fail on devices that are present more than once.
duplicate = 1; duplicate = 1;
fprintf (stderr, "error: duplicate device: %s\n", mcu_name[i]); fprintf (stderr, "error: duplicate device: %s\n", mcus[i]->name);
} }
} }
...@@ -122,8 +181,7 @@ int main (void) ...@@ -122,8 +181,7 @@ int main (void)
{ {
arch_id = mcu->arch_id; arch_id = mcu->arch_id;
/* Start a new architecture: Flush the MCUs collected so far. */ // Start a new architecture: Flush the MCUs collected so far.
print_mcus (n_mcus); print_mcus (n_mcus);
n_mcus = 0; n_mcus = 0;
...@@ -133,7 +191,7 @@ int main (void) ...@@ -133,7 +191,7 @@ int main (void)
} }
else if (arch_id == (enum avr_arch_id) mcu->arch_id) else if (arch_id == (enum avr_arch_id) mcu->arch_id)
{ {
mcu_name[n_mcus++] = mcu->name; mcus[n_mcus++] = mcu;
} }
} }
......
...@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
"%(link_text_start) " \ "%(link_text_start) " \
"%(link_relax) " \ "%(link_relax) " \
"%(link_pmem_wrap) " \ "%(link_pmem_wrap) " \
"%(link_pm_base_address) " \
"%{shared:%eshared is not supported} " "%{shared:%eshared is not supported} "
#undef LIB_SPEC #undef LIB_SPEC
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment