Commit 4a2caf6c by Georg-Johann Lay Committed by Georg-Johann Lay

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
parent 768fbdd4
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> 2015-03-10 Ilya Enkovich <ilya.enkovich@intel.com>
* c-family/c.opt (fchkp-use-wrappers): New. * c-family/c.opt (fchkp-use-wrappers): New.
......
...@@ -330,7 +330,6 @@ avr-*-*) ...@@ -330,7 +330,6 @@ avr-*-*)
cpu_type=avr cpu_type=avr
c_target_objs="avr-c.o" c_target_objs="avr-c.o"
cxx_target_objs="avr-c.o" cxx_target_objs="avr-c.o"
extra_options="${extra_options} avr/avr-tables.opt"
;; ;;
bfin*-*) bfin*-*)
cpu_type=bfin cpu_type=bfin
...@@ -1090,18 +1089,21 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*) ...@@ -1090,18 +1089,21 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
tm_file="${tm_file} arm/aout.h vxworks-dummy.h arm/arm.h" tm_file="${tm_file} arm/aout.h vxworks-dummy.h arm/arm.h"
;; ;;
avr-*-rtems*) 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" 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" extra_objs="avr-devices.o avr-log.o"
;; ;;
avr-*-*) 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 if test x${with_avrlibc} != xno; then
tm_file="${tm_file} ${cpu_type}/avrlibc.h" tm_file="${tm_file} ${cpu_type}/avrlibc.h"
tm_defines="${tm_defines} WITH_AVRLIBC" tm_defines="${tm_defines} WITH_AVRLIBC"
fi fi
tmake_file="${tmake_file} avr/t-avr avr/t-multilib" tmake_file="${tmake_file} avr/t-avr avr/t-multilib"
use_gcc_stdint=wrap use_gcc_stdint=wrap
extra_gcc_objs="driver-avr.o avr-devices.o"
extra_objs="avr-devices.o avr-log.o" extra_objs="avr-devices.o avr-log.o"
;; ;;
bfin*-elf*) bfin*-elf*)
......
...@@ -22,9 +22,11 @@ along with GCC; see the file COPYING3. If not see ...@@ -22,9 +22,11 @@ along with GCC; see the file COPYING3. If not see
#ifndef AVR_ARCH_H #ifndef AVR_ARCH_H
#define AVR_ARCH_H #define AVR_ARCH_H
#define AVR_MMCU_DEFAULT "avr2"
/* This enum supplies indices into the avr_arch_types[] table below. */ /* This enum supplies indices into the avr_arch_types[] table below. */
enum avr_arch enum avr_arch_id
{ {
ARCH_UNKNOWN, ARCH_UNKNOWN,
ARCH_AVR1, ARCH_AVR1,
...@@ -92,7 +94,7 @@ typedef struct ...@@ -92,7 +94,7 @@ typedef struct
const char *const macro; const char *const macro;
/* Architecture name. */ /* Architecture name. */
const char *const arch_name; const char *const name;
} avr_arch_t; } avr_arch_t;
...@@ -104,7 +106,7 @@ typedef struct ...@@ -104,7 +106,7 @@ typedef struct
const char *const name; const char *const name;
/* Index in avr_arch_types[]. */ /* Index in avr_arch_types[]. */
enum avr_arch arch; enum avr_arch_id arch_id;
/* device specific feature */ /* device specific feature */
int dev_attribute; int dev_attribute;
...@@ -166,7 +168,7 @@ enum avr_device_specific_features ...@@ -166,7 +168,7 @@ enum avr_device_specific_features
typedef struct typedef struct
{ {
/* Architecture ID. */ /* Architecture ID. */
enum avr_arch arch; enum avr_arch_id arch_id;
/* textinfo source to describe the archtiecture. */ /* textinfo source to describe the archtiecture. */
const char *texinfo; const char *texinfo;
...@@ -175,9 +177,11 @@ typedef struct ...@@ -175,9 +177,11 @@ typedef struct
/* Preprocessor macros to define depending on MCU type. */ /* Preprocessor macros to define depending on MCU type. */
extern const avr_arch_t avr_arch_types[]; 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_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 */ #endif /* AVR_ARCH_H */
...@@ -305,8 +305,11 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -305,8 +305,11 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
builtin_define_std ("AVR"); builtin_define_std ("AVR");
if (avr_current_arch->macro) /* __AVR_DEVICE_NAME__ and avr_mcu_types[].macro like __AVR_ATmega8__
cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_current_arch->macro); 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_RAMPD) cpp_define (pfile, "__AVR_HAVE_RAMPD__");
if (AVR_HAVE_RAMPX) cpp_define (pfile, "__AVR_HAVE_RAMPX__"); if (AVR_HAVE_RAMPX) cpp_define (pfile, "__AVR_HAVE_RAMPX__");
if (AVR_HAVE_RAMPY) cpp_define (pfile, "__AVR_HAVE_RAMPY__"); if (AVR_HAVE_RAMPY) cpp_define (pfile, "__AVR_HAVE_RAMPY__");
...@@ -316,14 +319,14 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -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_MOVW) cpp_define (pfile, "__AVR_HAVE_MOVW__");
if (AVR_HAVE_LPMX) cpp_define (pfile, "__AVR_HAVE_LPMX__"); 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__"); cpp_define (pfile, "__AVR_ASM_ONLY__");
if (AVR_HAVE_MUL) if (AVR_HAVE_MUL)
{ {
cpp_define (pfile, "__AVR_ENHANCED__"); cpp_define (pfile, "__AVR_ENHANCED__");
cpp_define (pfile, "__AVR_HAVE_MUL__"); 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_MEGA__");
cpp_define (pfile, "__AVR_HAVE_JMP_CALL__"); cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
...@@ -347,7 +350,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -347,7 +350,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
cpp_define (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x4000"); 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_HAVE_EIJMP_EICALL__");
cpp_define (pfile, "__AVR_3_BYTE_PC__"); cpp_define (pfile, "__AVR_3_BYTE_PC__");
...@@ -362,11 +365,10 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -362,11 +365,10 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
else else
cpp_define (pfile, "__AVR_HAVE_16BIT_SP__"); cpp_define (pfile, "__AVR_HAVE_16BIT_SP__");
if (avr_sp8)
cpp_define (pfile, "__AVR_SP8__");
if (AVR_HAVE_SPH) if (AVR_HAVE_SPH)
cpp_define (pfile, "__AVR_HAVE_SPH__"); cpp_define (pfile, "__AVR_HAVE_SPH__");
else
cpp_define (pfile, "__AVR_SP8__");
if (TARGET_NO_INTERRUPTS) if (TARGET_NO_INTERRUPTS)
cpp_define (pfile, "__NO_INTERRUPTS__"); cpp_define (pfile, "__NO_INTERRUPTS__");
...@@ -375,7 +377,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -375,7 +377,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
{ {
cpp_define (pfile, "__AVR_ERRATA_SKIP__"); 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__"); cpp_define (pfile, "__AVR_ERRATA_SKIP_JMP_CALL__");
} }
...@@ -383,7 +385,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -383,7 +385,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
cpp_define (pfile, "__AVR_ISA_RMW__"); cpp_define (pfile, "__AVR_ISA_RMW__");
cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x", cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x",
avr_current_arch->sfr_offset); avr_arch->sfr_offset);
#ifdef WITH_AVRLIBC #ifdef WITH_AVRLIBC
cpp_define (pfile, "__WITH_AVRLIBC__"); cpp_define (pfile, "__WITH_AVRLIBC__");
......
...@@ -21,9 +21,12 @@ ...@@ -21,9 +21,12 @@
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "diagnostic.h"
#include "tm.h" #include "tm.h"
#endif /* IN_GEN_AVR_MMCU_TEXI */ #endif /* IN_GEN_AVR_MMCU_TEXI */
#include "avr-arch.h"
/* List of all known AVR MCU architectures. /* List of all known AVR MCU architectures.
Order as of enum avr_arch from avr.h. */ Order as of enum avr_arch from avr.h. */
...@@ -31,7 +34,7 @@ const avr_arch_t ...@@ -31,7 +34,7 @@ const avr_arch_t
avr_arch_types[] = avr_arch_types[] =
{ {
/* unknown device specified */ /* 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 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 S U M PO L L I M A I a t F ff r
...@@ -116,3 +119,98 @@ avr_mcu_types[] = ...@@ -116,3 +119,98 @@ avr_mcu_types[] =
{ NULL, ARCH_UNKNOWN, AVR_ISA_NONE, NULL, 0, 0, 0, NULL } { 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
...@@ -24,11 +24,10 @@ ...@@ -24,11 +24,10 @@
This will regenerate / update the following source files: This will regenerate / update the following source files:
- $(srcdir)/config/avr/t-multilib - $(srcdir)/config/avr/t-multilib
- $(srcdir)/config/avr/avr-tables.opt
- $(srcdir)/doc/avr-mmcu.texi - $(srcdir)/doc/avr-mmcu.texi
After that, rebuild everything and check-in the new sources to the repo. 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: Before including this file, define a macro:
...@@ -53,8 +52,7 @@ ...@@ -53,8 +52,7 @@
N_FLASH Number of 64 KiB flash segments, rounded up. N_FLASH Number of 64 KiB flash segments, rounded up.
LIBRARY_NAME Used by the driver to linke startup code from avr-libc LIBRARY_NAME Used to define __AVR_DEV_LIB_NAME__.
as of crt<LIBRARY_NAME>.o
"avr2" must be first for the "0" default to work as intended. */ "avr2" must be first for the "0" default to work as intended. */
......
; -*- 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)
...@@ -234,10 +234,7 @@ static GTY(()) rtx xstring_empty; ...@@ -234,10 +234,7 @@ static GTY(()) rtx xstring_empty;
static GTY(()) rtx xstring_e; static GTY(()) rtx xstring_e;
/* Current architecture. */ /* Current architecture. */
const avr_arch_t *avr_current_arch; const avr_arch_t *avr_arch;
/* Current device. */
const avr_mcu_t *avr_current_device;
/* Section to put switch tables in. */ /* Section to put switch tables in. */
static GTY(()) section *progmem_swtable_section; static GTY(()) section *progmem_swtable_section;
...@@ -380,6 +377,49 @@ avr_register_passes (void) ...@@ -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'. */ /* Implement `TARGET_OPTION_OVERRIDE'. */
static void static void
...@@ -424,39 +464,24 @@ avr_option_override (void) ...@@ -424,39 +464,24 @@ avr_option_override (void)
if (flag_pie == 2) if (flag_pie == 2)
warning (OPT_fPIE, "-fPIE is not supported"); warning (OPT_fPIE, "-fPIE is not supported");
/* Search for mcu arch. if (!avr_set_core_architecture())
??? We should probably just put the architecture-default device return;
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;
/* RAM addresses of some SFRs common to all devices in respective arch. */ /* RAM addresses of some SFRs common to all devices in respective arch. */
/* SREG: Status Register containing flags like I (global IRQ) */ /* 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 */ /* 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.rampy = 0x3A + avr_arch->sfr_offset;
avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset; avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset; avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_current_arch->sfr_offset; avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
/* SP: Stack Pointer (SP_H:SP_L) */ /* 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; avr_addr.sp_h = avr_addr.sp_l + 1;
init_machine_status = avr_init_machine_status; init_machine_status = avr_init_machine_status;
...@@ -2328,7 +2353,7 @@ avr_print_operand (FILE *file, rtx x, int code) ...@@ -2328,7 +2353,7 @@ avr_print_operand (FILE *file, rtx x, int code)
else else
{ {
fprintf (file, HOST_WIDE_INT_PRINT_HEX, fprintf (file, HOST_WIDE_INT_PRINT_HEX,
ival - avr_current_arch->sfr_offset); ival - avr_arch->sfr_offset);
} }
} }
else else
...@@ -2396,7 +2421,7 @@ avr_print_operand (FILE *file, rtx x, int code) ...@@ -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)) if (GET_CODE (x) == SYMBOL_REF && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
avr_print_operand_address avr_print_operand_address
(file, plus_constant (HImode, x, -avr_current_arch->sfr_offset)); (file, plus_constant (HImode, x, -avr_arch->sfr_offset));
else else
fatal_insn ("bad address, not an I/O address:", x); fatal_insn ("bad address, not an I/O address:", x);
} }
...@@ -9246,12 +9271,11 @@ avr_pgm_check_var_decl (tree node) ...@@ -9246,12 +9271,11 @@ avr_pgm_check_var_decl (tree node)
if (avr_addrspace[as].segment >= avr_n_flash) if (avr_addrspace[as].segment >= avr_n_flash)
{ {
if (TYPE_P (node)) if (TYPE_P (node))
error ("%qT uses address space %qs beyond flash of %qs", error ("%qT uses address space %qs beyond flash of %d KiB",
node, avr_addrspace[as].name, avr_current_device->name); node, avr_addrspace[as].name, avr_n_flash);
else else
error ("%s %q+D uses address space %qs beyond flash of %qs", error ("%s %q+D uses address space %qs beyond flash of %d KiB",
reason, node, avr_addrspace[as].name, reason, node, avr_addrspace[as].name, avr_n_flash);
avr_current_device->name);
} }
else else
{ {
...@@ -9297,15 +9321,14 @@ avr_insert_attributes (tree node, tree *attributes) ...@@ -9297,15 +9321,14 @@ avr_insert_attributes (tree node, tree *attributes)
if (avr_addrspace[as].segment >= avr_n_flash) if (avr_addrspace[as].segment >= avr_n_flash)
{ {
error ("variable %q+D located in address space %qs" error ("variable %q+D located in address space %qs beyond flash "
" beyond flash of %qs", "of %d KiB", node, avr_addrspace[as].name, avr_n_flash);
node, avr_addrspace[as].name, avr_current_device->name);
} }
else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2) else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
{ {
error ("variable %q+D located in address space %qs" error ("variable %q+D located in address space %qs"
" which is not supported by %qs", " which is not supported for architecture %qs",
node, avr_addrspace[as].name, avr_current_arch->arch_name); node, avr_addrspace[as].name, avr_arch->name);
} }
if (!TYPE_READONLY (node0) if (!TYPE_READONLY (node0)
...@@ -9723,10 +9746,10 @@ avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) ...@@ -9723,10 +9746,10 @@ avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
static void static void
avr_file_start (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) if (avr_arch->asm_only)
error ("MCU %qs supported for assembler only", avr_current_device->name); error ("architecture %qs supported for assembler only", avr_mmcu);
default_file_start (); default_file_start ();
......
...@@ -60,19 +60,19 @@ enum ...@@ -60,19 +60,19 @@ enum
#define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile) #define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile)
#define AVR_HAVE_JMP_CALL (avr_current_arch->have_jmp_call) #define AVR_HAVE_JMP_CALL (avr_arch->have_jmp_call)
#define AVR_HAVE_MUL (avr_current_arch->have_mul) #define AVR_HAVE_MUL (avr_arch->have_mul)
#define AVR_HAVE_MOVW (avr_current_arch->have_movw_lpmx) #define AVR_HAVE_MOVW (avr_arch->have_movw_lpmx)
#define AVR_HAVE_LPM (!AVR_TINY) #define AVR_HAVE_LPM (!AVR_TINY)
#define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx) #define AVR_HAVE_LPMX (avr_arch->have_movw_lpmx)
#define AVR_HAVE_ELPM (avr_current_arch->have_elpm) #define AVR_HAVE_ELPM (avr_arch->have_elpm)
#define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx) #define AVR_HAVE_ELPMX (avr_arch->have_elpmx)
#define AVR_HAVE_RAMPD (avr_current_arch->have_rampd) #define AVR_HAVE_RAMPD (avr_arch->have_rampd)
#define AVR_HAVE_RAMPX (avr_current_arch->have_rampd) #define AVR_HAVE_RAMPX (avr_arch->have_rampd)
#define AVR_HAVE_RAMPY (avr_current_arch->have_rampd) #define AVR_HAVE_RAMPY (avr_arch->have_rampd)
#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm \ #define AVR_HAVE_RAMPZ (avr_arch->have_elpm \
|| avr_current_arch->have_rampd) || avr_arch->have_rampd)
#define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall) #define AVR_HAVE_EIJMP_EICALL (avr_arch->have_eijmp_eicall)
/* Handling of 8-bit SP versus 16-bit SP is as follows: /* Handling of 8-bit SP versus 16-bit SP is as follows:
...@@ -90,17 +90,16 @@ FIXME: DRIVER_SELF_SPECS has changed. ...@@ -90,17 +90,16 @@ FIXME: DRIVER_SELF_SPECS has changed.
__AVR_HAVE_8BIT_SP__ and __AVR_HAVE_16BIT_SP__. During multilib generation __AVR_HAVE_8BIT_SP__ and __AVR_HAVE_16BIT_SP__. During multilib generation
there is always __AVR_SP8__ == __AVR_HAVE_8BIT_SP__. */ there is always __AVR_SP8__ == __AVR_HAVE_8BIT_SP__. */
#define AVR_HAVE_8BIT_SP \ #define AVR_HAVE_8BIT_SP \
((avr_current_device->dev_attribute & AVR_SHORT_SP) \ (TARGET_TINY_STACK || avr_sp8)
|| TARGET_TINY_STACK || avr_sp8)
#define AVR_HAVE_SPH (!avr_sp8) #define AVR_HAVE_SPH (!avr_sp8)
#define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL) #define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL)
#define AVR_3_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_XMEGA (avr_arch->xmega_p)
#define AVR_TINY (avr_current_arch->tiny_p) #define AVR_TINY (avr_arch->tiny_p)
#define BITS_BIG_ENDIAN 0 #define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0 #define BYTES_BIG_ENDIAN 0
...@@ -492,25 +491,24 @@ typedef struct avr_args ...@@ -492,25 +491,24 @@ typedef struct avr_args
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ #define ADJUST_INSN_LENGTH(INSN, LENGTH) \
(LENGTH = avr_adjust_insn_length (INSN, LENGTH)) (LENGTH = avr_adjust_insn_length (INSN, LENGTH))
#define DRIVER_SELF_SPECS \ extern const char *avr_devicespecs_file (int, const char**);
" %{!mmcu=*:%{!march=*:-specs=device-specs/specs-avr2%s} " \
" %{march=*:-specs=device-specs/specs-%*%s}} " \
" %{mmcu=*:-specs=device-specs/specs-%*%s %<mmcu=*} "
/* We want cc1plus used as a preprocessor to pick up the cpp spec from the #define EXTRA_SPEC_FUNCTIONS \
per-device spec files */ { "device-specs-file", avr_devicespecs_file },
#define CPLUSPLUS_CPP_SPEC "%(cpp)"
#define LIBSTDCXX "gcc" /* Driver self specs has lmited functionality w.r.t. '%s' for dynamic specs.
/* No libstdc++ for now. Empty string doesn't work. */ 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. */ #undef DRIVER_SELF_SPECS
#define STARTFILE_SPEC "" #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*). */ /* This is the default without any -mmcu=* option. */
#define MULTILIB_DEFAULTS { "mmcu=avr2" } #define MULTILIB_DEFAULTS { "mmcu=" AVR_MMCU_DEFAULT }
#define TEST_HARD_REG_CLASS(CLASS, REGNO) \ #define TEST_HARD_REG_CLASS(CLASS, REGNO) \
TEST_HARD_REG_BIT (reg_class_contents[ (int) (CLASS)], REGNO) TEST_HARD_REG_BIT (reg_class_contents[ (int) (CLASS)], REGNO)
......
...@@ -18,21 +18,14 @@ ...@@ -18,21 +18,14 @@
; along with GCC; see the file COPYING3. If not see ; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>. ; <http://www.gnu.org/licenses/>.
HeaderInclude
config/avr/avr-arch.h
mcall-prologues mcall-prologues
Target Report Mask(CALL_PROLOGUES) Target Report Mask(CALL_PROLOGUES)
Use subroutines for function prologues and epilogues Use subroutines for function prologues and epilogues
mmcu= mmcu=
Target RejectNegative Joined Target RejectNegative Joined Var(avr_mmcu) MissingArgError(missing device or architecture after %qs)
-mmcu=MCU Select the target MCU -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= mn-flash=
Target RejectNegative Joined Var(avr_n_flash) UInteger Init(-1) Target RejectNegative Joined Var(avr_n_flash) UInteger Init(-1)
Set the number of 64 KiB flash segments Set the number of 64 KiB flash segments
......
...@@ -27,6 +27,18 @@ along with GCC; see the file COPYING3. If not see ...@@ -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 #undef LINK_GCC_C_SEQUENCE_SPEC
#define LINK_GCC_C_SEQUENCE_SPEC \ #define LINK_GCC_C_SEQUENCE_SPEC \
"--start-group %G %L --end-group" "--start-group %G %L --end-group"
/* 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);
}
...@@ -23,20 +23,31 @@ ...@@ -23,20 +23,31 @@
#define IN_GEN_AVR_MMCU_TEXI #define IN_GEN_AVR_MMCU_TEXI
#include "avr-arch.h"
#include "avr-devices.c" #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 #define GCC_DEFAULTS_H
#include "tm.h" #include "tm.h"
// Mimic the include order as specified in config.gcc::tm_file.
#include "specs.h"
#if defined (WITH_AVRLIBC) #if defined (WITH_AVRLIBC)
static const bool with_avrlibc = true; #include "avrlibc.h"
#else #endif
static const bool with_avrlibc = false;
#endif /* WITH_AVRLIBC */ #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. */ /* Return true iff STR starts with PREFIX. */
static bool static bool
...@@ -46,17 +57,41 @@ str_prefix_p (const char *str, const char *prefix) ...@@ -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 static void
print_mcu (const avr_mcu_t *mcu) print_mcu (const avr_mcu_t *mcu)
{ {
const char *sp8_spec; const char *sp8_spec;
const avr_mcu_t *arch_mcu; 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; ) for (arch_mcu = mcu; arch_mcu->macro; )
arch_mcu--; arch_mcu--;
if (arch_mcu->arch != mcu->arch) if (arch_mcu->arch_id != arch_id)
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
arch = &avr_arch_types[arch_id];
char name[100]; char name[100];
if (snprintf (name, sizeof name, "specs-%s", mcu->name) >= (int) sizeof name) if (snprintf (name, sizeof name, "specs-%s", mcu->name) >= (int) sizeof name)
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
...@@ -66,9 +101,12 @@ print_mcu (const avr_mcu_t *mcu) ...@@ -66,9 +101,12 @@ print_mcu (const avr_mcu_t *mcu)
bool errata_skip = 0 != (mcu->dev_attribute & AVR_ERRATA_SKIP); bool errata_skip = 0 != (mcu->dev_attribute & AVR_ERRATA_SKIP);
bool rmw = 0 != (mcu->dev_attribute & AVR_ISA_RMW); bool rmw = 0 != (mcu->dev_attribute & AVR_ISA_RMW);
bool sp8 = 0 != (mcu->dev_attribute & AVR_SHORT_SP); bool sp8 = 0 != (mcu->dev_attribute & AVR_SHORT_SP);
bool is_arch = NULL == mcu->macro;
bool is_device = ! is_arch;
if (mcu->macro == NULL if (is_arch
&& (mcu->arch == ARCH_AVR2 || mcu->arch == ARCH_AVR25)) && (ARCH_AVR2 == arch_id
|| ARCH_AVR25 == arch_id))
{ {
// Leave "avr2" and "avr25" alone. These two architectures are // Leave "avr2" and "avr25" alone. These two architectures are
// the only ones that mix devices with 8-bit SP and 16-bit SP. // 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) ...@@ -76,97 +114,124 @@ print_mcu (const avr_mcu_t *mcu)
} }
else else
{ {
sp8_spec = sp8 sp8_spec = sp8 ? "-msp8" :"%<msp8";
? " -msp8"
: " %<msp8";
} }
const char *errata_skip_spec = errata_skip fprintf (f, "#\n"
? " %{!mno-skip-bug:-mskip-bug}" "# Auto-generated specs for AVR ");
: " %{!mskip-bug:-mno-skip-bug}"; 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 fprintf (f, "*avrlibc_startfile:\n");
? " %{!mno-rmw: -mrmw}" if (is_device)
: " %{mrmw}"; 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" // avr-specific specs for the compilation / the compiler proper.
" %%{!march=*:-march=%s}"
" %s\n\n", arch_name, sp8_spec);
if (mcu->macro) fprintf (f, "*cc1_n_flash:\n"
fprintf (f, "*cpp:\n-D__AVR_DEV_LIB_NAME__=%s -D%s " "\t%%{!mn-flash=*:-mn-flash=%d}\n\n", mcu->n_flash);
"-D__AVR_DEVICE_NAME__=%s\n\n",
mcu->library_name, mcu->macro, mcu->name); 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); fprintf (f, "*asm_rmw:\n%s\n\n", rmw
if (mcu->n_flash != arch_mcu->n_flash) ? "\t%{!mno-rmw: -mrmw}"
fprintf (f, " %%{!mn-flash:-mn-flash=%d}", mcu->n_flash); : "\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, "\n\n");
fprintf (f, "*cc1plus:\n%s%s ", errata_skip_spec, rmw_spec); fprintf (f, "*link_relax:\n\t%s\n\n", LINK_RELAX_SPEC);
if (mcu->n_flash != arch_mcu->n_flash)
fprintf (f, " %%{!mn-flash:-mn-flash=%d}", mcu->n_flash); fprintf (f, "*link_arch:\n\t%s\n\n", LINK_ARCH_SPEC);
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_data_start:\n");
if (mcu->data_section_start if (mcu->data_section_start
!= avr_arch_types[mcu->arch].default_data_section_start) != arch->default_data_section_start)
fprintf (f, " -Tdata 0x%lX", 0x800000UL + mcu->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) 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"); fprintf (f, "*asm:\n\t%s\n\n", ASM_SPEC);
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, "*libgcc:\n"); fprintf (f, "*link:\n\t%s\n\n", LINK_SPEC);
if (has_libs)
fprintf (f, with_avrlibc fprintf (f, "*lib:\n\t%s\n\n", has_libs ? LIB_SPEC : "");
? "-lgcc -lm"
: "-lgcc"); fprintf (f, "*libgcc:\n\t%s\n\n", has_libs ? LIBGCC_SPEC : "");
fprintf (f, "\n\n");
fprintf (f, "*startfile:\n\t%s\n\n", STARTFILE_SPEC);
fprintf (f, "*endfile:\n%s\n\n", ENDFILE_SPEC);
fprintf (f, "*startfile:\n" fprintf (f, "# End of file\n");
"dev/%s/crt1.o%%s\n\n", mcu->name);
} }
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#define IN_GEN_AVR_MMCU_TEXI #define IN_GEN_AVR_MMCU_TEXI
#include "avr-arch.h"
#include "avr-devices.c" #include "avr-devices.c"
static const char* static const char*
...@@ -97,7 +96,7 @@ print_mcus (size_t n_mcus) ...@@ -97,7 +96,7 @@ print_mcus (size_t n_mcus)
int main (void) int main (void)
{ {
enum avr_arch arch = ARCH_UNKNOWN; enum avr_arch_id arch_id = ARCH_UNKNOWN;
size_t i, n_mcus = 0; size_t i, n_mcus = 0;
const avr_mcu_t *mcu; const avr_mcu_t *mcu;
...@@ -120,7 +119,7 @@ int main (void) ...@@ -120,7 +119,7 @@ int main (void)
{ {
if (mcu->macro == NULL) if (mcu->macro == NULL)
{ {
arch = mcu->arch; 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. */
...@@ -128,10 +127,10 @@ int main (void) ...@@ -128,10 +127,10 @@ int main (void)
n_mcus = 0; n_mcus = 0;
for (i = 0; i < sizeof (avr_texinfo) / sizeof (*avr_texinfo); i++) 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); 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; mcu_name[n_mcus++] = mcu->name;
} }
......
...@@ -97,7 +97,7 @@ BEGIN { ...@@ -97,7 +97,7 @@ BEGIN {
cores[n_cores] = core cores[n_cores] = core
n_cores++ n_cores++
tiny_stack[core] = 0 tiny_stack[core] = 0
option[core] = "march=" core option[core] = "mmcu=" core
next next
} }
......
#!/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
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
;; Return true if OP is a valid address for lower half of I/O space. ;; Return true if OP is a valid address for lower half of I/O space.
(define_special_predicate "low_io_address_operand" (define_special_predicate "low_io_address_operand"
(ior (and (match_code "const_int") (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))")) 0, 0x20 - GET_MODE_SIZE (mode))"))
(and (match_code "symbol_ref") (and (match_code "symbol_ref")
(match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_IO_LOW")))) (match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_IO_LOW"))))
...@@ -53,13 +53,13 @@ ...@@ -53,13 +53,13 @@
;; Return true if OP is a valid address for high half of I/O space. ;; Return true if OP is a valid address for high half of I/O space.
(define_predicate "high_io_address_operand" (define_predicate "high_io_address_operand"
(and (match_code "const_int") (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)"))) 0x20, 0x3F)")))
;; Return true if OP is a valid address of I/O space. ;; Return true if OP is a valid address of I/O space.
(define_special_predicate "io_address_operand" (define_special_predicate "io_address_operand"
(ior (and (match_code "const_int") (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))")) 0, 0x40 - GET_MODE_SIZE (mode))"))
(and (match_code "symbol_ref") (and (match_code "symbol_ref")
(match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_IO")))) (match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_IO"))))
......
/* 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 ""
...@@ -16,8 +16,14 @@ ...@@ -16,8 +16,14 @@
# along with GCC; see the file COPYING3. If not see # along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. # <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 \ avr-devices.o: $(srcdir)/config/avr/avr-devices.c \
$(srcdir)/config/avr/avr-mcus.def \ $(srcdir)/config/avr/avr-mcus.def \
$(srcdir)/config/avr/avr-arch.h \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
...@@ -49,15 +55,9 @@ AVR_MCUS = $(srcdir)/config/avr/avr-mcus.def ...@@ -49,15 +55,9 @@ AVR_MCUS = $(srcdir)/config/avr/avr-mcus.def
.PHONY: avr-mcus .PHONY: avr-mcus
avr-mcus: $(srcdir)/config/avr/t-multilib \ avr-mcus: $(srcdir)/config/avr/t-multilib \
$(srcdir)/config/avr/avr-tables.opt \
$(srcdir)/doc/avr-mmcu.texi ; @true $(srcdir)/doc/avr-mmcu.texi ; @true
# Make sure that -mmcu= is supported for devices from avr-mcus.def and # Make sure that native -mmcu= support is in sync with -mmcu= documentation.
# 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.
gen-avr-mmcu-texi$(build_exeext): $(srcdir)/config/avr/gen-avr-mmcu-texi.c \ gen-avr-mmcu-texi$(build_exeext): $(srcdir)/config/avr/gen-avr-mmcu-texi.c \
$(AVR_MCUS) $(srcdir)/config/avr/avr-devices.c \ $(AVR_MCUS) $(srcdir)/config/avr/avr-devices.c \
$(srcdir)/config/avr/avr-arch.h $(srcdir)/config/avr/avr-arch.h
...@@ -84,7 +84,7 @@ install-device-specs: s-device-specs installdirs ...@@ -84,7 +84,7 @@ install-device-specs: s-device-specs installdirs
-rm -rf $(DESTDIR)$(libsubdir)/device-specs -rm -rf $(DESTDIR)$(libsubdir)/device-specs
mkdir $(DESTDIR)$(libsubdir)/device-specs mkdir $(DESTDIR)$(libsubdir)/device-specs
-for file in device-specs/*; do \ -for file in device-specs/*; do \
$(INSTALL_PROGRAM) $${file} $(DESTDIR)$(libsubdir)/$${file}; \ $(INSTALL_DATA) $${file} $(DESTDIR)$(libsubdir)/$${file}; \
done done
# Map -mmcu= to the right multilib variant # Map -mmcu= to the right multilib variant
......
...@@ -21,21 +21,21 @@ ...@@ -21,21 +21,21 @@
# along with GCC; see the file COPYING3. If not see # along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. # <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_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack avr25/tiny-stack
MULTILIB_EXCEPTIONS = \ MULTILIB_EXCEPTIONS = \
march=avr3/msp8 \ mmcu=avr3/msp8 \
march=avr31/msp8 \ mmcu=avr31/msp8 \
march=avr35/msp8 \ mmcu=avr35/msp8 \
march=avr4/msp8 \ mmcu=avr4/msp8 \
march=avr5/msp8 \ mmcu=avr5/msp8 \
march=avr51/msp8 \ mmcu=avr51/msp8 \
march=avr6/msp8 \ mmcu=avr6/msp8 \
march=avrxmega2/msp8 \ mmcu=avrxmega2/msp8 \
march=avrxmega4/msp8 \ mmcu=avrxmega4/msp8 \
march=avrxmega5/msp8 \ mmcu=avrxmega5/msp8 \
march=avrxmega6/msp8 \ mmcu=avrxmega6/msp8 \
march=avrxmega7/msp8 \ mmcu=avrxmega7/msp8 \
march=avrtiny/msp8 mmcu=avrtiny/msp8
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