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>
PR target/92448
......@@ -126,6 +126,9 @@ typedef struct
/* Flash size in bytes. */
int flash_size;
/* Offset where flash is seen in the RAM address space. */
int flash_pm_offset;
} avr_mcu_t;
/* AVR device specific features.
......
......@@ -117,12 +117,12 @@ avr_texinfo[] =
const avr_mcu_t
avr_mcu_types[] =
{
#define AVR_MCU(NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, TEXT_SEC, FLASH_SIZE)\
{ 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, PMOFF },
#include "avr-mcus.def"
#undef AVR_MCU
/* 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[] =
"# #include <avr/io.h>\n"
"#\n"
"# will include the desired device header. For ATmega8A the supplement\n"
"# to *cpp would read\n"
"# to *cpp_avrlibc would read\n"
"#\n"
"# -D__AVR_DEV_LIB_NAME__=m8a\n"
"\n";
......@@ -132,6 +132,14 @@ print_mcu (const avr_mcu_t *mcu)
bool rcall = (mcu->dev_attribute & AVR_ISA_RCALL);
bool is_arch = mcu->macro == NULL;
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
&& (ARCH_AVR2 == arch_id
......@@ -262,6 +270,14 @@ print_mcu (const avr_mcu_t *mcu)
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.
if (is_device)
......@@ -273,10 +289,26 @@ print_mcu (const avr_mcu_t *mcu)
#if defined (WITH_AVRLIBC)
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
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, "\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");
}
......
......@@ -25,8 +25,8 @@
#include "avr-devices.c"
static const char*
mcu_name[sizeof avr_mcu_types / sizeof avr_mcu_types[0]];
static const avr_mcu_t*
mcus[sizeof avr_mcu_types / sizeof avr_mcu_types[0]];
static int letter (char c)
{
......@@ -39,21 +39,80 @@ static int digit (char c)
}
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;
const char *b = *(const char* const*) vb;
return strncmp (str, prefix, strlen (prefix)) == 0;
}
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
`atmega16' without `atmega161' etc. between them. */
while (digit (*a))
val = 10 * val + (*a++) - '0';
}
return val;
}
if (letter (*a) && digit (*b))
return -1;
/* Compare two MCUs and order them for easy lookup. */
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))
return 1;
// First, group MCUs according to their pure-letter prefix.
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)
return *a - *b;
......@@ -74,20 +133,20 @@ print_mcus (size_t n_mcus)
if (!n_mcus)
return;
qsort (mcu_name, n_mcus, sizeof (char*), comparator);
qsort (mcus, n_mcus, sizeof (avr_mcu_t*), comparator);
printf ("@*@var{mcu}@tie{}=");
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;
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)
{
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);
n_mcus = 0;
......@@ -133,7 +191,7 @@ int main (void)
}
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
"%(link_text_start) " \
"%(link_relax) " \
"%(link_pmem_wrap) " \
"%(link_pm_base_address) " \
"%{shared:%eshared is not supported} "
#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