aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2015-03-10 09:50:41 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2015-03-10 09:50:41 +0000
commit4a2caf6ced93a63e1703870ed67385d3f89da474 (patch)
treefa8390902e4ef79ccff88b2c2384679848448dc0 /gcc
parent768fbdd49e8535486ea71eebc507c3b813521a1b (diff)
downloadgcc-4a2caf6ced93a63e1703870ed67385d3f89da474.zip
gcc-4a2caf6ced93a63e1703870ed67385d3f89da474.tar.gz
gcc-4a2caf6ced93a63e1703870ed67385d3f89da474.tar.bz2
re PR target/65296 ([avr] fix various issues with specs file generation)
PR target/65296 * config.gcc (extra_options) [avr]: Remove. (extra_gcc_objs) [avr]: Use driver-avr.o, avr-devices.o. (tm_file) [avr]: Add avr/specs.h after avr/avr.h. (tm_defines) [avr-*-rtems*]: Add WITH_RTEMS. * config/avr/avr.opt (config/avr/avr-arch.h): Remove include. (-mmcu=): Add Var and MissingArgError properties. (-march=): Remove. * config/avr/genmultilib.awk: Use -mmcu= instead of -march=. * config/avr/t-multilib: Regenerate. * config/avr/specs.h: New file. * config/avr/driver-avr.c: New file. * config/avr/genopt.sh: Remove file. * config/avr/avr-tables.opt: Remove file. * config/avr/predicates.md (avr_current_arch): Rename to avr_arch. * config/avr/avr-c.c: Same. * avr-arch.h: Same. (avr_current_device): Remove proto. * config/avr/avr.h (avr_current_arch): Rename to avr_arch. (AVR_HAVE_8BIT_SP): Don't depend on avr_current_device. (EXTRA_SPEC_FUNCTIONS): Define. (avr_devicespecs_file): New specs function proto. (DRIVER_SELF_SPECS): Use device-specs-file spec function. * config/avr/avr.c (avr_current_arch): Rename to avr_arch. (avr_current_device): Remove definition and usage. (avr_set_core_architecture): New static function. (avr_option_override): Use it. * config/avr/avr-devices.c (diagnostic.h, avr-arch.h): Include them. (mcu_name): New static array. (comparator, avr_archs_str, avr_mcus_str): New static functions. (avr_inform_devices, avr_inform_core_architectures): New functions. * config/avr/gen-avr-mmcu-specs.c (avr-arch.h, specs.h): Include. (avrlibc.h) [WITH_AVRLIBC]: Include. (../rtems.h, rtems.h) [WITH_RTEMS]: Include. (print_mcu): Rewrite from scratch. * config/avr/avrlibc.h (LIB_SPEC, LIBGCC_SPEC, STARTFILE_SPEC): Forward to avr-specific specs defined in device-specs file. * config/avr/t-avr (driver-avr.o): New rule. (avr-devices.o): Depend on avr-arch.h. (avr-mcus): No more depend on avr-tables.opt. (avr-tables.opt): Remove rule. (install-device-specs): Use INSTALL_DATA, not INSTALL_PROGRAM. From-SVN: r221316
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog46
-rw-r--r--gcc/config.gcc8
-rw-r--r--gcc/config/avr/avr-arch.h16
-rw-r--r--gcc/config/avr/avr-c.c22
-rw-r--r--gcc/config/avr/avr-devices.c100
-rw-r--r--gcc/config/avr/avr-mcus.def6
-rw-r--r--gcc/config/avr/avr-tables.opt73
-rw-r--r--gcc/config/avr/avr.c109
-rw-r--r--gcc/config/avr/avr.h60
-rw-r--r--gcc/config/avr/avr.opt9
-rw-r--r--gcc/config/avr/avrlibc.h12
-rw-r--r--gcc/config/avr/driver-avr.c124
-rw-r--r--gcc/config/avr/gen-avr-mmcu-specs.c227
-rw-r--r--gcc/config/avr/gen-avr-mmcu-texi.c9
-rw-r--r--gcc/config/avr/genmultilib.awk2
-rwxr-xr-xgcc/config/avr/genopt.sh58
-rw-r--r--gcc/config/avr/predicates.md6
-rw-r--r--gcc/config/avr/specs.h77
-rw-r--r--gcc/config/avr/t-avr16
-rw-r--r--gcc/config/avr/t-multilib28
20 files changed, 659 insertions, 349 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4224656..357d629 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,49 @@
+2015-03-10 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/65296
+ * config.gcc (extra_options) [avr]: Remove.
+ (extra_gcc_objs) [avr]: Use driver-avr.o, avr-devices.o.
+ (tm_file) [avr]: Add avr/specs.h after avr/avr.h.
+ (tm_defines) [avr-*-rtems*]: Add WITH_RTEMS.
+
+ * config/avr/avr.opt (config/avr/avr-arch.h): Remove include.
+ (-mmcu=): Add Var and MissingArgError properties.
+ (-march=): Remove.
+ * config/avr/genmultilib.awk: Use -mmcu= instead of -march=.
+ * config/avr/t-multilib: Regenerate.
+ * config/avr/specs.h: New file.
+ * config/avr/driver-avr.c: New file.
+ * config/avr/genopt.sh: Remove file.
+ * config/avr/avr-tables.opt: Remove file.
+ * config/avr/predicates.md (avr_current_arch): Rename to avr_arch.
+ * config/avr/avr-c.c: Same.
+ * avr-arch.h: Same.
+ (avr_current_device): Remove proto.
+ * config/avr/avr.h (avr_current_arch): Rename to avr_arch.
+ (AVR_HAVE_8BIT_SP): Don't depend on avr_current_device.
+ (EXTRA_SPEC_FUNCTIONS): Define.
+ (avr_devicespecs_file): New specs function proto.
+ (DRIVER_SELF_SPECS): Use device-specs-file spec function.
+ * config/avr/avr.c (avr_current_arch): Rename to avr_arch.
+ (avr_current_device): Remove definition and usage.
+ (avr_set_core_architecture): New static function.
+ (avr_option_override): Use it.
+ * config/avr/avr-devices.c (diagnostic.h, avr-arch.h): Include them.
+ (mcu_name): New static array.
+ (comparator, avr_archs_str, avr_mcus_str): New static functions.
+ (avr_inform_devices, avr_inform_core_architectures): New functions.
+ * config/avr/gen-avr-mmcu-specs.c (avr-arch.h, specs.h): Include.
+ (avrlibc.h) [WITH_AVRLIBC]: Include.
+ (../rtems.h, rtems.h) [WITH_RTEMS]: Include.
+ (print_mcu): Rewrite from scratch.
+ * config/avr/avrlibc.h (LIB_SPEC, LIBGCC_SPEC, STARTFILE_SPEC):
+ Forward to avr-specific specs defined in device-specs file.
+ * config/avr/t-avr (driver-avr.o): New rule.
+ (avr-devices.o): Depend on avr-arch.h.
+ (avr-mcus): No more depend on avr-tables.opt.
+ (avr-tables.opt): Remove rule.
+ (install-device-specs): Use INSTALL_DATA, not INSTALL_PROGRAM.
+
2015-03-10 Ilya Enkovich <ilya.enkovich@intel.com>
* c-family/c.opt (fchkp-use-wrappers): New.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 69d1670b..cb08a5c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -330,7 +330,6 @@ avr-*-*)
cpu_type=avr
c_target_objs="avr-c.o"
cxx_target_objs="avr-c.o"
- extra_options="${extra_options} avr/avr-tables.opt"
;;
bfin*-*)
cpu_type=bfin
@@ -1090,18 +1089,21 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
tm_file="${tm_file} arm/aout.h vxworks-dummy.h arm/arm.h"
;;
avr-*-rtems*)
- tm_file="elfos.h avr/elf.h avr/avr-arch.h avr/avr.h dbxelf.h avr/rtems.h rtems.h newlib-stdint.h"
+ tm_file="elfos.h avr/elf.h avr/avr-arch.h avr/avr.h avr/specs.h dbxelf.h avr/rtems.h rtems.h newlib-stdint.h"
+ tm_defines="${tm_defines} WITH_RTEMS"
tmake_file="${tmake_file} avr/t-avr avr/t-multilib avr/t-rtems"
+ extra_gcc_objs="driver-avr.o avr-devices.o"
extra_objs="avr-devices.o avr-log.o"
;;
avr-*-*)
- tm_file="elfos.h avr/elf.h avr/avr-arch.h avr/avr.h dbxelf.h avr/avr-stdint.h"
+ tm_file="elfos.h avr/elf.h avr/avr-arch.h avr/avr.h avr/specs.h dbxelf.h avr/avr-stdint.h"
if test x${with_avrlibc} != xno; then
tm_file="${tm_file} ${cpu_type}/avrlibc.h"
tm_defines="${tm_defines} WITH_AVRLIBC"
fi
tmake_file="${tmake_file} avr/t-avr avr/t-multilib"
use_gcc_stdint=wrap
+ extra_gcc_objs="driver-avr.o avr-devices.o"
extra_objs="avr-devices.o avr-log.o"
;;
bfin*-elf*)
diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h
index eb46f2c..baf780b 100644
--- a/gcc/config/avr/avr-arch.h
+++ b/gcc/config/avr/avr-arch.h
@@ -22,9 +22,11 @@ along with GCC; see the file COPYING3. If not see
#ifndef AVR_ARCH_H
#define AVR_ARCH_H
+#define AVR_MMCU_DEFAULT "avr2"
+
/* This enum supplies indices into the avr_arch_types[] table below. */
-enum avr_arch
+enum avr_arch_id
{
ARCH_UNKNOWN,
ARCH_AVR1,
@@ -92,7 +94,7 @@ typedef struct
const char *const macro;
/* Architecture name. */
- const char *const arch_name;
+ const char *const name;
} avr_arch_t;
@@ -104,7 +106,7 @@ typedef struct
const char *const name;
/* Index in avr_arch_types[]. */
- enum avr_arch arch;
+ enum avr_arch_id arch_id;
/* device specific feature */
int dev_attribute;
@@ -166,7 +168,7 @@ enum avr_device_specific_features
typedef struct
{
/* Architecture ID. */
- enum avr_arch arch;
+ enum avr_arch_id arch_id;
/* textinfo source to describe the archtiecture. */
const char *texinfo;
@@ -175,9 +177,11 @@ typedef struct
/* Preprocessor macros to define depending on MCU type. */
extern const avr_arch_t avr_arch_types[];
-extern const avr_arch_t *avr_current_arch;
+extern const avr_arch_t *avr_arch;
extern const avr_mcu_t avr_mcu_types[];
-extern const avr_mcu_t *avr_current_device;
+
+extern void avr_inform_devices (void);
+extern void avr_inform_core_architectures (void);
#endif /* AVR_ARCH_H */
diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c
index ffac50c..351982f 100644
--- a/gcc/config/avr/avr-c.c
+++ b/gcc/config/avr/avr-c.c
@@ -305,8 +305,11 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
builtin_define_std ("AVR");
- if (avr_current_arch->macro)
- cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_current_arch->macro);
+ /* __AVR_DEVICE_NAME__ and avr_mcu_types[].macro like __AVR_ATmega8__
+ are defined by -D command option, see device-specs file. */
+
+ if (avr_arch->macro)
+ cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_arch->macro);
if (AVR_HAVE_RAMPD) cpp_define (pfile, "__AVR_HAVE_RAMPD__");
if (AVR_HAVE_RAMPX) cpp_define (pfile, "__AVR_HAVE_RAMPX__");
if (AVR_HAVE_RAMPY) cpp_define (pfile, "__AVR_HAVE_RAMPY__");
@@ -316,14 +319,14 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
if (AVR_HAVE_MOVW) cpp_define (pfile, "__AVR_HAVE_MOVW__");
if (AVR_HAVE_LPMX) cpp_define (pfile, "__AVR_HAVE_LPMX__");
- if (avr_current_arch->asm_only)
+ if (avr_arch->asm_only)
cpp_define (pfile, "__AVR_ASM_ONLY__");
if (AVR_HAVE_MUL)
{
cpp_define (pfile, "__AVR_ENHANCED__");
cpp_define (pfile, "__AVR_HAVE_MUL__");
}
- if (avr_current_arch->have_jmp_call)
+ if (avr_arch->have_jmp_call)
{
cpp_define (pfile, "__AVR_MEGA__");
cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
@@ -347,7 +350,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
cpp_define (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x4000");
}
- if (avr_current_arch->have_eijmp_eicall)
+ if (AVR_HAVE_EIJMP_EICALL)
{
cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
cpp_define (pfile, "__AVR_3_BYTE_PC__");
@@ -362,11 +365,10 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
else
cpp_define (pfile, "__AVR_HAVE_16BIT_SP__");
- if (avr_sp8)
- cpp_define (pfile, "__AVR_SP8__");
-
if (AVR_HAVE_SPH)
cpp_define (pfile, "__AVR_HAVE_SPH__");
+ else
+ cpp_define (pfile, "__AVR_SP8__");
if (TARGET_NO_INTERRUPTS)
cpp_define (pfile, "__NO_INTERRUPTS__");
@@ -375,7 +377,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
{
cpp_define (pfile, "__AVR_ERRATA_SKIP__");
- if (avr_current_arch->have_jmp_call)
+ if (AVR_HAVE_JMP_CALL)
cpp_define (pfile, "__AVR_ERRATA_SKIP_JMP_CALL__");
}
@@ -383,7 +385,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
cpp_define (pfile, "__AVR_ISA_RMW__");
cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x",
- avr_current_arch->sfr_offset);
+ avr_arch->sfr_offset);
#ifdef WITH_AVRLIBC
cpp_define (pfile, "__WITH_AVRLIBC__");
diff --git a/gcc/config/avr/avr-devices.c b/gcc/config/avr/avr-devices.c
index 387686a..082e789 100644
--- a/gcc/config/avr/avr-devices.c
+++ b/gcc/config/avr/avr-devices.c
@@ -21,9 +21,12 @@
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "diagnostic.h"
#include "tm.h"
#endif /* IN_GEN_AVR_MMCU_TEXI */
+#include "avr-arch.h"
+
/* List of all known AVR MCU architectures.
Order as of enum avr_arch from avr.h. */
@@ -31,7 +34,7 @@ const avr_arch_t
avr_arch_types[] =
{
/* unknown device specified */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, "avr2" },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, AVR_MMCU_DEFAULT },
/*
A M J LM E E E X R T d S S O A
S U M PO L L I M A I a t F ff r
@@ -116,3 +119,98 @@ avr_mcu_types[] =
{ NULL, ARCH_UNKNOWN, AVR_ISA_NONE, NULL, 0, 0, 0, NULL }
};
+
+
+
+#ifndef IN_GEN_AVR_MMCU_TEXI
+
+/* Copy-pastes from `gen-avr-mmcu-texi.c' follow... */
+
+static const char*
+mcu_name[sizeof avr_mcu_types / sizeof avr_mcu_types[0]];
+
+static int
+comparator (const void *va, const void *vb)
+{
+ const char *a = *(const char* const*) va;
+ const char *b = *(const char* const*) vb;
+
+ while (*a && *b)
+ {
+ /* Make letters smaller than digits so that `atmega16a' follows
+ `atmega16' without `atmega161' etc. between them. */
+
+ if (ISALPHA (*a) && ISDIGIT (*b))
+ return -1;
+
+ if (ISDIGIT (*a) && ISALPHA (*b))
+ return 1;
+
+ if (*a != *b)
+ return *a - *b;
+
+ a++;
+ b++;
+ }
+
+ return *a - *b;
+}
+
+
+static char*
+avr_archs_str (void)
+{
+ char *archs = concat ("", NULL);
+
+ // Build of core architectures' names.
+
+ for (const avr_mcu_t *mcu = avr_mcu_types; mcu->name; mcu++)
+ if (!mcu->macro)
+ archs = concat (archs, " ", avr_arch_types[mcu->arch_id].name, NULL);
+
+ return archs;
+}
+
+
+static char*
+avr_mcus_str (void)
+{
+ size_t n_mcus = 0;
+ char *mcus = concat ("", NULL);
+
+ // Build array of proper devices' names.
+
+ for (const avr_mcu_t *mcu = avr_mcu_types; mcu->name; mcu++)
+ if (mcu->macro)
+ mcu_name[n_mcus++] = mcu->name;
+
+ // Sort MCUs so that they are displayed in the same canonical order as
+ // in doc/avr-mcus.texi.
+
+ qsort (mcu_name, n_mcus, sizeof (char*), comparator);
+
+ for (size_t i = 0; i < n_mcus; i++)
+ mcus = concat (mcus, " ", mcu_name[i], NULL);
+
+ return mcus;
+}
+
+
+void
+avr_inform_devices (void)
+{
+ char *mcus = avr_mcus_str ();
+ inform (input_location, "devices natively supported:%s", mcus);
+ free (mcus);
+}
+
+
+void
+avr_inform_core_architectures (void)
+{
+ char *archs = avr_archs_str ();
+ inform (input_location, "supported core architectures:%s", archs);
+ free (archs);
+}
+
+#endif // IN_GEN_AVR_MMCU_TEXI
diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def
index f357ce5..547f785 100644
--- a/gcc/config/avr/avr-mcus.def
+++ b/gcc/config/avr/avr-mcus.def
@@ -24,11 +24,10 @@
This will regenerate / update the following source files:
- $(srcdir)/config/avr/t-multilib
- - $(srcdir)/config/avr/avr-tables.opt
- $(srcdir)/doc/avr-mmcu.texi
After that, rebuild everything and check-in the new sources to the repo.
- The device list below has to be kept in sync with AVR-LibC.
+ The device list below should be kept in sync with AVR-LibC.
Before including this file, define a macro:
@@ -53,8 +52,7 @@
N_FLASH Number of 64 KiB flash segments, rounded up.
- LIBRARY_NAME Used by the driver to linke startup code from avr-libc
- as of crt<LIBRARY_NAME>.o
+ LIBRARY_NAME Used to define __AVR_DEV_LIB_NAME__.
"avr2" must be first for the "0" default to work as intended. */
diff --git a/gcc/config/avr/avr-tables.opt b/gcc/config/avr/avr-tables.opt
deleted file mode 100644
index 66e54fc..0000000
--- a/gcc/config/avr/avr-tables.opt
+++ /dev/null
@@ -1,73 +0,0 @@
-; -*- buffer-read-only: t -*-
-; Generated automatically by genopt.sh from avr-mcus.def.
-
-; Copyright (C) 2011-2015 Free Software Foundation, Inc.
-;
-; This file is part of GCC.
-;
-; GCC is free software; you can redistribute it and/or modify it under
-; the terms of the GNU General Public License as published by the Free
-; Software Foundation; either version 3, or (at your option) any later
-; version.
-;
-; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-; WARRANTY; without even the implied warranty of MERCHANTABILITY or
-; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-; for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with GCC; see the file COPYING3. If not see
-; <http://www.gnu.org/licenses/>.
-
-Enum
-Name(avr_arch) Type(enum avr_arch)
-Known MCU architectures:
-
-EnumValue
-Enum(avr_arch) String(avr2) Value(ARCH_AVR2)
-
-EnumValue
-Enum(avr_arch) String(avr25) Value(ARCH_AVR25)
-
-EnumValue
-Enum(avr_arch) String(avr3) Value(ARCH_AVR3)
-
-EnumValue
-Enum(avr_arch) String(avr31) Value(ARCH_AVR31)
-
-EnumValue
-Enum(avr_arch) String(avr35) Value(ARCH_AVR35)
-
-EnumValue
-Enum(avr_arch) String(avr4) Value(ARCH_AVR4)
-
-EnumValue
-Enum(avr_arch) String(avr5) Value(ARCH_AVR5)
-
-EnumValue
-Enum(avr_arch) String(avr51) Value(ARCH_AVR51)
-
-EnumValue
-Enum(avr_arch) String(avr6) Value(ARCH_AVR6)
-
-EnumValue
-Enum(avr_arch) String(avrxmega2) Value(ARCH_AVRXMEGA2)
-
-EnumValue
-Enum(avr_arch) String(avrxmega4) Value(ARCH_AVRXMEGA4)
-
-EnumValue
-Enum(avr_arch) String(avrxmega5) Value(ARCH_AVRXMEGA5)
-
-EnumValue
-Enum(avr_arch) String(avrxmega6) Value(ARCH_AVRXMEGA6)
-
-EnumValue
-Enum(avr_arch) String(avrxmega7) Value(ARCH_AVRXMEGA7)
-
-EnumValue
-Enum(avr_arch) String(avrtiny) Value(ARCH_AVRTINY)
-
-EnumValue
-Enum(avr_arch) String(avr1) Value(ARCH_AVR1)
-
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 827b280..68d5ddc 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -234,10 +234,7 @@ static GTY(()) rtx xstring_empty;
static GTY(()) rtx xstring_e;
/* Current architecture. */
-const avr_arch_t *avr_current_arch;
-
-/* Current device. */
-const avr_mcu_t *avr_current_device;
+const avr_arch_t *avr_arch;
/* Section to put switch tables in. */
static GTY(()) section *progmem_swtable_section;
@@ -380,6 +377,49 @@ avr_register_passes (void)
}
+/* Set `avr_arch' as specified by `-mmcu='.
+ Return true on success. */
+
+static bool
+avr_set_core_architecture (void)
+{
+ /* Search for mcu core architecture. */
+
+ if (!avr_mmcu)
+ avr_mmcu = AVR_MMCU_DEFAULT;
+
+ avr_arch = &avr_arch_types[0];
+
+ for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
+ {
+ if (NULL == mcu->name)
+ {
+ /* Reached the end of `avr_mcu_types'. This should actually never
+ happen as options are provided by device-specs. It could be a
+ typo in a device-specs or calling the compiler proper directly
+ with -mmcu=<device>. */
+
+ error ("unknown core architecture %qs specified with %qs",
+ avr_mmcu, "-mmcu=");
+ avr_inform_core_architectures ();
+ break;
+ }
+ else if (0 == strcmp (mcu->name, avr_mmcu)
+ // Is this a proper architecture ?
+ && NULL == mcu->macro)
+ {
+ avr_arch = &avr_arch_types[mcu->arch_id];
+ if (avr_n_flash < 0)
+ avr_n_flash = mcu->n_flash;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
/* Implement `TARGET_OPTION_OVERRIDE'. */
static void
@@ -424,39 +464,24 @@ avr_option_override (void)
if (flag_pie == 2)
warning (OPT_fPIE, "-fPIE is not supported");
- /* Search for mcu arch.
- ??? We should probably just put the architecture-default device
- settings in the architecture struct and remove any notion of a current
- device from gcc. */
-
- for (avr_current_device = avr_mcu_types; ; avr_current_device++)
- {
- if (!avr_current_device->name)
- fatal_error (input_location, "mcu not found");
- if (!avr_current_device->macro
- && avr_current_device->arch == avr_arch_index)
- break;
- }
-
- avr_current_arch = &avr_arch_types[avr_arch_index];
- if (avr_n_flash < 0)
- avr_n_flash = avr_current_device->n_flash;
+ if (!avr_set_core_architecture())
+ return;
/* RAM addresses of some SFRs common to all devices in respective arch. */
/* SREG: Status Register containing flags like I (global IRQ) */
- avr_addr.sreg = 0x3F + avr_current_arch->sfr_offset;
+ avr_addr.sreg = 0x3F + avr_arch->sfr_offset;
/* RAMPZ: Address' high part when loading via ELPM */
- avr_addr.rampz = 0x3B + avr_current_arch->sfr_offset;
+ avr_addr.rampz = 0x3B + avr_arch->sfr_offset;
- avr_addr.rampy = 0x3A + avr_current_arch->sfr_offset;
- avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset;
- avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset;
- avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_current_arch->sfr_offset;
+ avr_addr.rampy = 0x3A + avr_arch->sfr_offset;
+ avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
+ avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
+ avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
/* SP: Stack Pointer (SP_H:SP_L) */
- avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
+ avr_addr.sp_l = 0x3D + avr_arch->sfr_offset;
avr_addr.sp_h = avr_addr.sp_l + 1;
init_machine_status = avr_init_machine_status;
@@ -2328,7 +2353,7 @@ avr_print_operand (FILE *file, rtx x, int code)
else
{
fprintf (file, HOST_WIDE_INT_PRINT_HEX,
- ival - avr_current_arch->sfr_offset);
+ ival - avr_arch->sfr_offset);
}
}
else
@@ -2396,7 +2421,7 @@ avr_print_operand (FILE *file, rtx x, int code)
{
if (GET_CODE (x) == SYMBOL_REF && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
avr_print_operand_address
- (file, plus_constant (HImode, x, -avr_current_arch->sfr_offset));
+ (file, plus_constant (HImode, x, -avr_arch->sfr_offset));
else
fatal_insn ("bad address, not an I/O address:", x);
}
@@ -9246,12 +9271,11 @@ avr_pgm_check_var_decl (tree node)
if (avr_addrspace[as].segment >= avr_n_flash)
{
if (TYPE_P (node))
- error ("%qT uses address space %qs beyond flash of %qs",
- node, avr_addrspace[as].name, avr_current_device->name);
+ error ("%qT uses address space %qs beyond flash of %d KiB",
+ node, avr_addrspace[as].name, avr_n_flash);
else
- error ("%s %q+D uses address space %qs beyond flash of %qs",
- reason, node, avr_addrspace[as].name,
- avr_current_device->name);
+ error ("%s %q+D uses address space %qs beyond flash of %d KiB",
+ reason, node, avr_addrspace[as].name, avr_n_flash);
}
else
{
@@ -9297,15 +9321,14 @@ avr_insert_attributes (tree node, tree *attributes)
if (avr_addrspace[as].segment >= avr_n_flash)
{
- error ("variable %q+D located in address space %qs"
- " beyond flash of %qs",
- node, avr_addrspace[as].name, avr_current_device->name);
+ error ("variable %q+D located in address space %qs beyond flash "
+ "of %d KiB", node, avr_addrspace[as].name, avr_n_flash);
}
else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
{
error ("variable %q+D located in address space %qs"
- " which is not supported by %qs",
- node, avr_addrspace[as].name, avr_current_arch->arch_name);
+ " which is not supported for architecture %qs",
+ node, avr_addrspace[as].name, avr_arch->name);
}
if (!TYPE_READONLY (node0)
@@ -9723,10 +9746,10 @@ avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
static void
avr_file_start (void)
{
- int sfr_offset = avr_current_arch->sfr_offset;
+ int sfr_offset = avr_arch->sfr_offset;
- if (avr_current_arch->asm_only)
- error ("MCU %qs supported for assembler only", avr_current_device->name);
+ if (avr_arch->asm_only)
+ error ("architecture %qs supported for assembler only", avr_mmcu);
default_file_start ();
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 1f2f3da..9963766 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -60,19 +60,19 @@ enum
#define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile)
-#define AVR_HAVE_JMP_CALL (avr_current_arch->have_jmp_call)
-#define AVR_HAVE_MUL (avr_current_arch->have_mul)
-#define AVR_HAVE_MOVW (avr_current_arch->have_movw_lpmx)
+#define AVR_HAVE_JMP_CALL (avr_arch->have_jmp_call)
+#define AVR_HAVE_MUL (avr_arch->have_mul)
+#define AVR_HAVE_MOVW (avr_arch->have_movw_lpmx)
#define AVR_HAVE_LPM (!AVR_TINY)
-#define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx)
-#define AVR_HAVE_ELPM (avr_current_arch->have_elpm)
-#define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx)
-#define AVR_HAVE_RAMPD (avr_current_arch->have_rampd)
-#define AVR_HAVE_RAMPX (avr_current_arch->have_rampd)
-#define AVR_HAVE_RAMPY (avr_current_arch->have_rampd)
-#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm \
- || avr_current_arch->have_rampd)
-#define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
+#define AVR_HAVE_LPMX (avr_arch->have_movw_lpmx)
+#define AVR_HAVE_ELPM (avr_arch->have_elpm)
+#define AVR_HAVE_ELPMX (avr_arch->have_elpmx)
+#define AVR_HAVE_RAMPD (avr_arch->have_rampd)
+#define AVR_HAVE_RAMPX (avr_arch->have_rampd)
+#define AVR_HAVE_RAMPY (avr_arch->have_rampd)
+#define AVR_HAVE_RAMPZ (avr_arch->have_elpm \
+ || avr_arch->have_rampd)
+#define AVR_HAVE_EIJMP_EICALL (avr_arch->have_eijmp_eicall)
/* Handling of 8-bit SP versus 16-bit SP is as follows:
@@ -90,17 +90,16 @@ FIXME: DRIVER_SELF_SPECS has changed.
__AVR_HAVE_8BIT_SP__ and __AVR_HAVE_16BIT_SP__. During multilib generation
there is always __AVR_SP8__ == __AVR_HAVE_8BIT_SP__. */
-#define AVR_HAVE_8BIT_SP \
- ((avr_current_device->dev_attribute & AVR_SHORT_SP) \
- || TARGET_TINY_STACK || avr_sp8)
+#define AVR_HAVE_8BIT_SP \
+ (TARGET_TINY_STACK || avr_sp8)
#define AVR_HAVE_SPH (!avr_sp8)
#define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL)
#define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
-#define AVR_XMEGA (avr_current_arch->xmega_p)
-#define AVR_TINY (avr_current_arch->tiny_p)
+#define AVR_XMEGA (avr_arch->xmega_p)
+#define AVR_TINY (avr_arch->tiny_p)
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0
@@ -492,25 +491,24 @@ typedef struct avr_args
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
(LENGTH = avr_adjust_insn_length (INSN, LENGTH))
-#define DRIVER_SELF_SPECS \
- " %{!mmcu=*:%{!march=*:-specs=device-specs/specs-avr2%s} " \
- " %{march=*:-specs=device-specs/specs-%*%s}} " \
- " %{mmcu=*:-specs=device-specs/specs-%*%s %<mmcu=*} "
+extern const char *avr_devicespecs_file (int, const char**);
-/* We want cc1plus used as a preprocessor to pick up the cpp spec from the
- per-device spec files */
-#define CPLUSPLUS_CPP_SPEC "%(cpp)"
+#define EXTRA_SPEC_FUNCTIONS \
+ { "device-specs-file", avr_devicespecs_file },
-#define LIBSTDCXX "gcc"
-/* No libstdc++ for now. Empty string doesn't work. */
+/* Driver self specs has lmited functionality w.r.t. '%s' for dynamic specs.
+ Apply '%s' to a static string to inflate the file (directory) name which
+ is used to diagnose problems with reading the specs file. */
-/* The actual definition will come from the device-specific spec file. */
-#define STARTFILE_SPEC ""
+#undef DRIVER_SELF_SPECS
+#define DRIVER_SELF_SPECS \
+ " %:device-specs-file(device-specs%s %{mmcu=*:%*})"
-#define ENDFILE_SPEC ""
+/* No libstdc++ for now. Empty string doesn't work. */
+#define LIBSTDCXX "gcc"
-/* This is the default without any -mmcu=* option (AT90S*). */
-#define MULTILIB_DEFAULTS { "mmcu=avr2" }
+/* This is the default without any -mmcu=* option. */
+#define MULTILIB_DEFAULTS { "mmcu=" AVR_MMCU_DEFAULT }
#define TEST_HARD_REG_CLASS(CLASS, REGNO) \
TEST_HARD_REG_BIT (reg_class_contents[ (int) (CLASS)], REGNO)
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index ab35264..d99c56e 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -18,21 +18,14 @@
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
-HeaderInclude
-config/avr/avr-arch.h
-
mcall-prologues
Target Report Mask(CALL_PROLOGUES)
Use subroutines for function prologues and epilogues
mmcu=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(avr_mmcu) MissingArgError(missing device or architecture after %qs)
-mmcu=MCU Select the target MCU
-march=
-Target RejectNegative Joined Var(avr_arch_index) Init(ARCH_AVR2) Enum(avr_arch)
--march=ARCH Select target architecture
-
mn-flash=
Target RejectNegative Joined Var(avr_n_flash) UInteger Init(-1)
Set the number of 64 KiB flash segments
diff --git a/gcc/config/avr/avrlibc.h b/gcc/config/avr/avrlibc.h
index b8801a7..a49eced 100644
--- a/gcc/config/avr/avrlibc.h
+++ b/gcc/config/avr/avrlibc.h
@@ -27,6 +27,18 @@ along with GCC; see the file COPYING3. If not see
*/
+#undef LIB_SPEC
+#define LIB_SPEC \
+ " -lc %(avrlibc_devicelib) "
+
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC \
+ " -lgcc -lm "
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ " %(avrlibc_startfile) "
+
#undef LINK_GCC_C_SEQUENCE_SPEC
#define LINK_GCC_C_SEQUENCE_SPEC \
"--start-group %G %L --end-group"
diff --git a/gcc/config/avr/driver-avr.c b/gcc/config/avr/driver-avr.c
new file mode 100644
index 0000000..4b39910
--- /dev/null
+++ b/gcc/config/avr/driver-avr.c
@@ -0,0 +1,124 @@
+/* Subroutines for the gcc driver.
+ Copyright (C) 2009-2015 Free Software Foundation, Inc.
+ Contributed by Georg-Johann Lay <avr@gjlay.de>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "diagnostic.h"
+#include "tm.h"
+
+static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
+
+static const char specfiles_doc_url[] =
+ "http://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html";
+
+
+static const char*
+avr_diagnose_devicespecs_error (const char *mcu, const char *filename)
+{
+ error ("cannot access device-specs for %qs expected at %qs",
+ mcu, filename);
+
+ // Inform about natively supported devices and cores.
+
+ if (strncmp (mcu, "avr", strlen ("avr")))
+ avr_inform_devices ();
+
+ avr_inform_core_architectures ();
+
+ inform (input_location, "you can provide your own specs files, "
+ "see <%s> for details", specfiles_doc_url);
+
+ return "";
+}
+
+
+/* Implement spec function `device-specs-fileĀ“.
+
+ Compose -specs=<specs-file-name>. If everything went well then argv[0]
+ is the inflated specs directory and argv[1] is a device or core name as
+ supplied to -mmcu=*. */
+
+const char*
+avr_devicespecs_file (int argc, const char **argv)
+{
+ char *specfile_name;
+ const char *mmcu = NULL;
+
+#ifdef DEBUG_SPECS
+ if (verbose_flag)
+ fnotice (stderr, "Running spec function '%s' with %d args\n\n",
+ __FUNCTION__, argc);
+#endif
+
+ switch (argc)
+ {
+ case 0:
+ fatal_error (input_location,
+ "bad usage of spec function %qs", "device-specs-file");
+ return "";
+
+ case 1:
+ mmcu = AVR_MMCU_DEFAULT;
+ break;
+
+ case 2:
+ mmcu = argv[1];
+ break;
+
+ default:
+ error ("specified option %qs more than once", "-mmcu=");
+ return "";
+ }
+
+ specfile_name = concat (argv[0], dir_separator_str, "specs-", mmcu, NULL);
+
+#ifdef DEBUG_SPECS
+ if (verbose_flag)
+ fnotice (stderr, "'%s': mmcu='%s'\n'%s': specfile='%s'\n\n",
+ __FUNCTION__, mmcu, __FUNCTION__, specfile_name);
+#endif
+
+ // Filter out silly -mmcu= arguments like "foo bar".
+
+ for (const char *s = mmcu; *s; s++)
+ if (!ISALNUM (*s)
+ && '-' != *s
+ && '_' != *s)
+ {
+ error ("strange device name %qs after %qs: bad character %qc",
+ mmcu, "-mmcu=", *s);
+ return "";
+ }
+
+ if (/* When building / configuring the compiler we might get a relative path
+ as supplied by "-B.". Assume that the specs file exists and MCU is
+ a core, not a proper device then, i.e. we have "-mmcu=avr*". */
+ (0 == strncmp (mmcu, "avr", strlen ("avr"))
+ && specfile_name[0] == '.')
+ /* vanilla */
+ || (IS_ABSOLUTE_PATH (specfile_name)
+ && !access (specfile_name, R_OK)))
+ {
+ return concat ("-specs=", specfile_name, NULL);
+ }
+
+ return avr_diagnose_devicespecs_error (mmcu, specfile_name);
+}
diff --git a/gcc/config/avr/gen-avr-mmcu-specs.c b/gcc/config/avr/gen-avr-mmcu-specs.c
index 9dcd4a0..bdc747c 100644
--- a/gcc/config/avr/gen-avr-mmcu-specs.c
+++ b/gcc/config/avr/gen-avr-mmcu-specs.c
@@ -23,20 +23,31 @@
#define IN_GEN_AVR_MMCU_TEXI
-#include "avr-arch.h"
#include "avr-devices.c"
+// Get rid of "defaults.h". We just need tm.h for `WITH_AVRLIBS' and
+// and `WITH_RTEMS'. */
#define GCC_DEFAULTS_H
#include "tm.h"
+// Mimic the include order as specified in config.gcc::tm_file.
+
+#include "specs.h"
+
#if defined (WITH_AVRLIBC)
-static const bool with_avrlibc = true;
-#else
-static const bool with_avrlibc = false;
-#endif /* WITH_AVRLIBC */
+#include "avrlibc.h"
+#endif
+
+#if defined (WITH_RTEMS)
+#include "../rtems.h"
+#include "rtems.h"
+#endif
+#define SPECFILE_DOC_URL \
+ "http://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html"
+
/* Return true iff STR starts with PREFIX. */
static bool
@@ -46,17 +57,41 @@ str_prefix_p (const char *str, const char *prefix)
}
+static const char header[] =
+ "#\n"
+ "# Generated by : ./gcc/config/avr/gen-avr-mmcu-specs.c\n"
+ "# Generated from : ./gcc/config/gcc.c\n"
+ "# ./gcc/config/avr/specs.h\n"
+#if defined (WITH_RTEMS)
+ "# ./gcc/config/rtems.h\n"
+ "# ./gcc/config/avr/rtems.h\n"
+#endif
+#if defined (WITH_AVRLIBC)
+ "# ./gcc/config/avr/avrlibc.h\n"
+#endif
+ "# Used by : avr-gcc compiler driver\n"
+ "# Used for : building command options for sub-processes\n"
+ "#\n"
+ "# See <" SPECFILE_DOC_URL ">\n"
+ "# for a documentation of spec files.\n"
+ "\n";
+
+
static void
print_mcu (const avr_mcu_t *mcu)
{
const char *sp8_spec;
const avr_mcu_t *arch_mcu;
+ const avr_arch_t *arch;
+ enum avr_arch_id arch_id = mcu->arch_id;
for (arch_mcu = mcu; arch_mcu->macro; )
arch_mcu--;
- if (arch_mcu->arch != mcu->arch)
+ if (arch_mcu->arch_id != arch_id)
exit (EXIT_FAILURE);
+ arch = &avr_arch_types[arch_id];
+
char name[100];
if (snprintf (name, sizeof name, "specs-%s", mcu->name) >= (int) sizeof name)
exit (EXIT_FAILURE);
@@ -66,9 +101,12 @@ print_mcu (const avr_mcu_t *mcu)
bool errata_skip = 0 != (mcu->dev_attribute & AVR_ERRATA_SKIP);
bool rmw = 0 != (mcu->dev_attribute & AVR_ISA_RMW);
bool sp8 = 0 != (mcu->dev_attribute & AVR_SHORT_SP);
+ bool is_arch = NULL == mcu->macro;
+ bool is_device = ! is_arch;
- if (mcu->macro == NULL
- && (mcu->arch == ARCH_AVR2 || mcu->arch == ARCH_AVR25))
+ if (is_arch
+ && (ARCH_AVR2 == arch_id
+ || ARCH_AVR25 == arch_id))
{
// Leave "avr2" and "avr25" alone. These two architectures are
// the only ones that mix devices with 8-bit SP and 16-bit SP.
@@ -76,97 +114,124 @@ print_mcu (const avr_mcu_t *mcu)
}
else
{
- sp8_spec = sp8
- ? " -msp8"
- : " %<msp8";
+ sp8_spec = sp8 ? "-msp8" :"%<msp8";
}
- const char *errata_skip_spec = errata_skip
- ? " %{!mno-skip-bug:-mskip-bug}"
- : " %{!mskip-bug:-mno-skip-bug}";
+ fprintf (f, "#\n"
+ "# Auto-generated specs for AVR ");
+ if (is_arch)
+ fprintf (f, "core architecture %s\n", arch->name);
+ else
+ fprintf (f, "device %s (core %s, %d-bit SP)\n",
+ mcu->name, arch->name, sp8 ? 8 : 16);
+ fprintf (f, "%s\n", header);
+
+ // avrlibc-specific specs for linking / thelinker.
- const char *rmw_spec = rmw
- ? " %{!mno-rmw: -mrmw}"
- : " %{mrmw}";
+ fprintf (f, "*avrlibc_startfile:\n");
+ if (is_device)
+ fprintf (f, "\tdev/%s/crt1.o%%s", mcu->name);
+ fprintf (f, "\n\n");
- const char *arch_name = avr_arch_types[mcu->arch].arch_name;
+ fprintf (f, "*avrlibc_devicelib:\n");
+ if (is_device)
+ fprintf (f, "\tdev/%s/libdev.a%%s", mcu->name);
+ fprintf (f, "\n\n");
- fprintf (f, "*self_spec:\n"
- " %%{!march=*:-march=%s}"
- " %s\n\n", arch_name, sp8_spec);
+ // avr-specific specs for the compilation / the compiler proper.
- if (mcu->macro)
- fprintf (f, "*cpp:\n-D__AVR_DEV_LIB_NAME__=%s -D%s "
- "-D__AVR_DEVICE_NAME__=%s\n\n",
- mcu->library_name, mcu->macro, mcu->name);
+ fprintf (f, "*cc1_n_flash:\n"
+ "\t%%{!mn-flash=*:-mn-flash=%d}\n\n", mcu->n_flash);
+
+ fprintf (f, "*cc1_rmw:\n%s\n\n", rmw
+ ? "\t%{!mno-rmw: -mrmw}"
+ : "\t%{mrmw}");
+
+ fprintf (f, "*cc1_errata_skip:\n%s\n\n", errata_skip
+ ? "\t%{!mno-skip-bug: -mskip-bug}"
+ : "\t%{!mskip-bug: -mno-skip-bug}");
+
+ // avr-specific specs for assembling / the assembler.
+
+ fprintf (f, "*asm_arch:\n\t-mmcu=%s\n\n", arch->name);
+
+ fprintf (f, "*asm_relax:\n\t%s\n\n", ASM_RELAX_SPEC);
- fprintf (f, "*cc1:\n%s%s", errata_skip_spec, rmw_spec);
- if (mcu->n_flash != arch_mcu->n_flash)
- fprintf (f, " %%{!mn-flash:-mn-flash=%d}", mcu->n_flash);
+ fprintf (f, "*asm_rmw:\n%s\n\n", rmw
+ ? "\t%{!mno-rmw: -mrmw}"
+ : "\t%{mrmw}");
+
+ fprintf (f, "*asm_errata_skip:\n%s\n\n", errata_skip
+ ? "\t%{mno-skip-bug}"
+ : "\t%{!mskip-bug: -mno-skip-bug}");
+
+ // avr-specific specs for linking / the linker.
+
+ int wrap_k =
+ str_prefix_p (mcu->name, "at90usb8") ? 8
+ : str_prefix_p (mcu->name, "atmega16") ? 16
+ : (str_prefix_p (mcu->name, "atmega32")
+ || str_prefix_p (mcu->name, "at90can32")) ? 32
+ : (str_prefix_p (mcu->name, "atmega64")
+ || str_prefix_p (mcu->name, "at90can64")
+ || str_prefix_p (mcu->name, "at90usb64")) ? 64
+ : 0;
+
+ fprintf (f, "*link_pmem_wrap:\n");
+ if (wrap_k)
+ fprintf (f, "\t%%{mpmem-wrap-around: --pmem-wrap-around=%dk}", wrap_k);
fprintf (f, "\n\n");
- fprintf (f, "*cc1plus:\n%s%s ", errata_skip_spec, rmw_spec);
- if (mcu->n_flash != arch_mcu->n_flash)
- fprintf (f, " %%{!mn-flash:-mn-flash=%d}", mcu->n_flash);
- fprintf (f, (" %%{!frtti: -fno-rtti}"
- " %%{!fenforce-eh-specs: -fno-enforce-eh-specs}"
- " %%{!fexceptions: -fno-exceptions}\n\n"));
-
- fprintf (f, "*asm:\n"
- " %%{march=*:-mmcu=%%*}"
- " %%{mrelax: --mlink-relax}"
- " %s%s\n\n", rmw_spec, (errata_skip
- ? " %{mno-skip-bug}"
- : " %{!mskip-bug:-mno-skip-bug}"));
- fprintf (f, "*link:\n"
- " %%{mrelax:--relax");
- {
- int wrap_k =
- str_prefix_p (mcu->name, "at90usb8") ? 8
- : str_prefix_p (mcu->name, "atmega16") ? 16
- : (str_prefix_p (mcu->name, "atmega32")
- || str_prefix_p (mcu->name, "at90can32")) ? 32
- : (str_prefix_p (mcu->name, "atmega64")
- || str_prefix_p (mcu->name, "at90can64")
- || str_prefix_p (mcu->name, "at90usb64")) ? 64
- : 0;
-
- if (wrap_k)
- fprintf (f, " %%{mpmem-wrap-around: --pmem-wrap-around=%dk}", wrap_k);
- }
- fprintf (f, "}"
- " %%{march=*:-m%%*}");
+ fprintf (f, "*link_relax:\n\t%s\n\n", LINK_RELAX_SPEC);
+
+ fprintf (f, "*link_arch:\n\t%s\n\n", LINK_ARCH_SPEC);
+ fprintf (f, "*link_data_start:\n");
if (mcu->data_section_start
- != avr_arch_types[mcu->arch].default_data_section_start)
- fprintf (f, " -Tdata 0x%lX", 0x800000UL + mcu->data_section_start);
+ != arch->default_data_section_start)
+ fprintf (f, "\t-Tdata 0x%lX", 0x800000UL + mcu->data_section_start);
+ fprintf (f, "\n\n");
+ fprintf (f, "*link_text_start:\n");
if (mcu->text_section_start != 0x0)
- fprintf (f, " -Ttext 0x%lX", 0UL + mcu->text_section_start);
+ fprintf (f, "\t-Ttext 0x%lX", 0UL + mcu->text_section_start);
+ fprintf (f, "\n\n");
+
+ // Default specs. Rewritten to the device-specific specs file so
+ // they can be adjusted as needed.
+
+ bool has_libs = arch_id != ARCH_AVR1;
+
+ fprintf (f, "*self_spec:\n");
+ if (is_device)
+ fprintf (f, "\t%%{!mmcu=avr*: %%<mmcu=* -mmcu=%s} ", arch->name);
+ fprintf (f, "%s\n\n", sp8_spec);
+
+ fprintf (f, "*cpp:\n");
+ if (is_device)
+ fprintf (f,"\t-D__AVR_DEV_LIB_NAME__=%s"
+ " -D%s"
+ " -D__AVR_DEVICE_NAME__=%s",
+ mcu->library_name, mcu->macro, mcu->name);
+ fprintf (f, "\n\n");
- fprintf (f, " %%{shared:%%eshared is not supported}\n\n");
+ fprintf (f, "*cc1:\n\t%s\n\n", CC1_SPEC);
- bool has_libs = mcu->arch != ARCH_AVR1;
+ fprintf (f, "*cc1plus:\n\t%s\n\n", CC1PLUS_SPEC);
- fprintf (f, "*lib:\n");
- if (has_libs)
- {
- fprintf (f, "-lc");
- if (with_avrlibc
- && mcu->macro)
- fprintf (f, " dev/%s/libdev.a%%s", mcu->name);
- }
- fprintf (f, "\n\n");
+ fprintf (f, "*asm:\n\t%s\n\n", ASM_SPEC);
- fprintf (f, "*libgcc:\n");
- if (has_libs)
- fprintf (f, with_avrlibc
- ? "-lgcc -lm"
- : "-lgcc");
- fprintf (f, "\n\n");
+ fprintf (f, "*link:\n\t%s\n\n", LINK_SPEC);
+
+ fprintf (f, "*lib:\n\t%s\n\n", has_libs ? LIB_SPEC : "");
+
+ fprintf (f, "*libgcc:\n\t%s\n\n", has_libs ? LIBGCC_SPEC : "");
+
+ fprintf (f, "*startfile:\n\t%s\n\n", STARTFILE_SPEC);
+
+ fprintf (f, "*endfile:\n%s\n\n", ENDFILE_SPEC);
- fprintf (f, "*startfile:\n"
- "dev/%s/crt1.o%%s\n\n", mcu->name);
+ fprintf (f, "# End of file\n");
}
diff --git a/gcc/config/avr/gen-avr-mmcu-texi.c b/gcc/config/avr/gen-avr-mmcu-texi.c
index a20d3bc..ea0de49 100644
--- a/gcc/config/avr/gen-avr-mmcu-texi.c
+++ b/gcc/config/avr/gen-avr-mmcu-texi.c
@@ -22,7 +22,6 @@
#define IN_GEN_AVR_MMCU_TEXI
-#include "avr-arch.h"
#include "avr-devices.c"
static const char*
@@ -97,7 +96,7 @@ print_mcus (size_t n_mcus)
int main (void)
{
- enum avr_arch arch = ARCH_UNKNOWN;
+ enum avr_arch_id arch_id = ARCH_UNKNOWN;
size_t i, n_mcus = 0;
const avr_mcu_t *mcu;
@@ -120,7 +119,7 @@ int main (void)
{
if (mcu->macro == NULL)
{
- arch = mcu->arch;
+ arch_id = mcu->arch_id;
/* Start a new architecture: Flush the MCUs collected so far. */
@@ -128,10 +127,10 @@ int main (void)
n_mcus = 0;
for (i = 0; i < sizeof (avr_texinfo) / sizeof (*avr_texinfo); i++)
- if (arch == avr_texinfo[i].arch)
+ if (arch_id == avr_texinfo[i].arch_id)
printf ("@item %s\n%s\n", mcu->name, avr_texinfo[i].texinfo);
}
- else if (arch == (enum avr_arch) mcu->arch)
+ else if (arch_id == (enum avr_arch_id) mcu->arch_id)
{
mcu_name[n_mcus++] = mcu->name;
}
diff --git a/gcc/config/avr/genmultilib.awk b/gcc/config/avr/genmultilib.awk
index 4f0b1a1..903322e 100644
--- a/gcc/config/avr/genmultilib.awk
+++ b/gcc/config/avr/genmultilib.awk
@@ -97,7 +97,7 @@ BEGIN {
cores[n_cores] = core
n_cores++
tiny_stack[core] = 0
- option[core] = "march=" core
+ option[core] = "mmcu=" core
next
}
diff --git a/gcc/config/avr/genopt.sh b/gcc/config/avr/genopt.sh
deleted file mode 100755
index 39775ca..0000000
--- a/gcc/config/avr/genopt.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/sh
-# Generate avr-tables.opt from the list in avr-mcus.def.
-# Copyright (C) 2011-2015 Free Software Foundation, Inc.
-#
-# This file is part of GCC.
-#
-# GCC is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GCC is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3. If not see
-# <http://www.gnu.org/licenses/>.
-
-cat <<EOF
-; -*- buffer-read-only: t -*-
-; Generated automatically by genopt.sh from avr-mcus.def.
-
-; Copyright (C) 2011-2015 Free Software Foundation, Inc.
-;
-; This file is part of GCC.
-;
-; GCC is free software; you can redistribute it and/or modify it under
-; the terms of the GNU General Public License as published by the Free
-; Software Foundation; either version 3, or (at your option) any later
-; version.
-;
-; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-; WARRANTY; without even the implied warranty of MERCHANTABILITY or
-; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-; for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with GCC; see the file COPYING3. If not see
-; <http://www.gnu.org/licenses/>.
-
-Enum
-Name(avr_arch) Type(enum avr_arch)
-Known MCU architectures:
-
-EOF
-
-awk -F'[(, ]+' 'BEGIN {
-}
-/^AVR_MCU.*NULL/ {
- name = $2
- value = $3
- gsub("\"", "", name)
- print "EnumValue"
- print "Enum(avr_arch) String(" name ") Value(" value ")"
- print ""
-}' $1
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index 28233dd..2d12bc6 100644
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -45,7 +45,7 @@
;; Return true if OP is a valid address for lower half of I/O space.
(define_special_predicate "low_io_address_operand"
(ior (and (match_code "const_int")
- (match_test "IN_RANGE (INTVAL (op) - avr_current_arch->sfr_offset,
+ (match_test "IN_RANGE (INTVAL (op) - avr_arch->sfr_offset,
0, 0x20 - GET_MODE_SIZE (mode))"))
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_IO_LOW"))))
@@ -53,13 +53,13 @@
;; Return true if OP is a valid address for high half of I/O space.
(define_predicate "high_io_address_operand"
(and (match_code "const_int")
- (match_test "IN_RANGE (INTVAL (op) - avr_current_arch->sfr_offset,
+ (match_test "IN_RANGE (INTVAL (op) - avr_arch->sfr_offset,
0x20, 0x3F)")))
;; Return true if OP is a valid address of I/O space.
(define_special_predicate "io_address_operand"
(ior (and (match_code "const_int")
- (match_test "IN_RANGE (INTVAL (op) - avr_current_arch->sfr_offset,
+ (match_test "IN_RANGE (INTVAL (op) - avr_arch->sfr_offset,
0, 0x40 - GET_MODE_SIZE (mode))"))
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_IO"))))
diff --git a/gcc/config/avr/specs.h b/gcc/config/avr/specs.h
new file mode 100644
index 0000000..b592692
--- /dev/null
+++ b/gcc/config/avr/specs.h
@@ -0,0 +1,77 @@
+/* Specs definitions for Atmel AVR back end.
+
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
+ Contributed by Georg-Johann Lay (avr@gjlay.de)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* Default specs layout. The actual definitions might be superseeded
+ by device- or OS- specific files, like avrlibc.h, ../rtems.h, etc.
+ The specs are repeated in the device specs files. Subspecs are
+ specs known to GCC or specs defined in the device specs files. */
+
+
+#undef CPLUSPLUS_CPP_SPEC
+#define CPLUSPLUS_CPP_SPEC \
+ "%(cpp)"
+
+#undef CC1_SPEC
+#define CC1_SPEC \
+ "%(cc1_n_flash) " \
+ "%(cc1_errata_skip) " \
+ "%(cc1_rmw) "
+
+#undef CC1PLUS_SPEC
+#define CC1PLUS_SPEC \
+ "%(cc1) " \
+ "%{!frtti:-fno-rtti} " \
+ "%{!fenforce-eh-specs:-fno-enforce-eh-specs} " \
+ "%{!fexceptions:-fno-exceptions} "
+
+#define ASM_RELAX_SPEC \
+ "%{mrelax:--mlink-relax} "
+
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "%(asm_arch) " \
+ "%(asm_relax) " \
+ "%(asm_rmw) " \
+ "%(asm_errata_skip) "
+
+#define LINK_ARCH_SPEC \
+ "%{mmcu=*:-m%*} "
+
+#define LINK_RELAX_SPEC \
+ "%{mrelax:--relax %(link_pmem_wrap)} "
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "%(link_arch) " \
+ "%(link_data_start) " \
+ "%(link_text_start) " \
+ "%(link_relax) " \
+ "%{shared:%eshared is not supported} "
+
+#undef LIB_SPEC
+#define LIB_SPEC " -lc "
+
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC " -lgcc "
+
+#define STARTFILE_SPEC ""
+#define ENDFILE_SPEC ""
diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr
index 4c5e23b..e297561 100644
--- a/gcc/config/avr/t-avr
+++ b/gcc/config/avr/t-avr
@@ -16,8 +16,14 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
+driver-avr.o: $(srcdir)/config/avr/driver-avr.c \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(srcdir)/config/avr/avr-arch.h $(TM_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
avr-devices.o: $(srcdir)/config/avr/avr-devices.c \
$(srcdir)/config/avr/avr-mcus.def \
+ $(srcdir)/config/avr/avr-arch.h \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
@@ -49,15 +55,9 @@ AVR_MCUS = $(srcdir)/config/avr/avr-mcus.def
.PHONY: avr-mcus
avr-mcus: $(srcdir)/config/avr/t-multilib \
- $(srcdir)/config/avr/avr-tables.opt \
$(srcdir)/doc/avr-mmcu.texi ; @true
-# Make sure that -mmcu= is supported for devices from avr-mcus.def and
-# all -mmcu= values are displayed on the help screen
-$(srcdir)/config/avr/avr-tables.opt: $(srcdir)/config/avr/genopt.sh $(AVR_MCUS)
- $(SHELL) $< $(AVR_MCUS) > $@
-
-# Make sure that -mmcu= support is in sync with -mmcu= documentation.
+# Make sure that native -mmcu= support is in sync with -mmcu= documentation.
gen-avr-mmcu-texi$(build_exeext): $(srcdir)/config/avr/gen-avr-mmcu-texi.c \
$(AVR_MCUS) $(srcdir)/config/avr/avr-devices.c \
$(srcdir)/config/avr/avr-arch.h
@@ -84,7 +84,7 @@ install-device-specs: s-device-specs installdirs
-rm -rf $(DESTDIR)$(libsubdir)/device-specs
mkdir $(DESTDIR)$(libsubdir)/device-specs
-for file in device-specs/*; do \
- $(INSTALL_PROGRAM) $${file} $(DESTDIR)$(libsubdir)/$${file}; \
+ $(INSTALL_DATA) $${file} $(DESTDIR)$(libsubdir)/$${file}; \
done
# Map -mmcu= to the right multilib variant
diff --git a/gcc/config/avr/t-multilib b/gcc/config/avr/t-multilib
index 1c0e2cd..4f80db7 100644
--- a/gcc/config/avr/t-multilib
+++ b/gcc/config/avr/t-multilib
@@ -21,21 +21,21 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-MULTILIB_OPTIONS = march=avr2/march=avr25/march=avr3/march=avr31/march=avr35/march=avr4/march=avr5/march=avr51/march=avr6/march=avrxmega2/march=avrxmega4/march=avrxmega5/march=avrxmega6/march=avrxmega7/march=avrtiny msp8
+MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7/mmcu=avrtiny msp8
MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack avr25/tiny-stack
MULTILIB_EXCEPTIONS = \
- march=avr3/msp8 \
- march=avr31/msp8 \
- march=avr35/msp8 \
- march=avr4/msp8 \
- march=avr5/msp8 \
- march=avr51/msp8 \
- march=avr6/msp8 \
- march=avrxmega2/msp8 \
- march=avrxmega4/msp8 \
- march=avrxmega5/msp8 \
- march=avrxmega6/msp8 \
- march=avrxmega7/msp8 \
- march=avrtiny/msp8
+ mmcu=avr3/msp8 \
+ mmcu=avr31/msp8 \
+ mmcu=avr35/msp8 \
+ mmcu=avr4/msp8 \
+ mmcu=avr5/msp8 \
+ mmcu=avr51/msp8 \
+ mmcu=avr6/msp8 \
+ mmcu=avrxmega2/msp8 \
+ mmcu=avrxmega4/msp8 \
+ mmcu=avrxmega5/msp8 \
+ mmcu=avrxmega6/msp8 \
+ mmcu=avrxmega7/msp8 \
+ mmcu=avrtiny/msp8