This patch fixes a problem with the -mtiny-stack option: Architectures avr2 and avr25 mix targets with 8-bit SP and 16-bit SP so that -mtiny-stack is no good for multilib selection:
If a frame pointer has to be set up from an 8-bit SP it is a difference if there is no SP_H or of the SP is just treated as if it was 8 bits wide. In the first case the high byte must be set to 0. In the second case SP_H can be read. That is: The patch uses the size of hard SP for multilib selection and generation. The user-settable -mtiny-stack is used for size of soft SP for optimization purposes, but does not influence multilib selection or generation or how FP is deduced from SP. Notable changes are: -mtiny-stack is no more a multilib option and its semantics restored as was before PR51345 introduced multilibs for 8-bit SP targets. Multilib selection is performed by a new undocumented option -msp8. This option is only used internally and need not to be specified on the command line. -msp8 is injected by DRIVER_SELF_SPECS as needed. There is no avr-specific multilib_raw[] needed any more. This turns genmultilib.awk considerably more easy and better to maintain. Much code could be kicked off. -print-multi-lib results are clean now. With the prior approach, -print-multi-lib printed phantom configurations like tiny-stack;@mmcu=at90s2313 avr25/tiny-stack;@mmcu=attiny13 which could confuse libc implementations like newlib or AVR-Libc during their configure stage as they evaluate -print-multilib-lib. Now -print-multi-lib yields .; avr25;@mmcu=avr25 avr3;@mmcu=avr3 avr31;@mmcu=avr31 avr35;@mmcu=avr35 avr4;@mmcu=avr4 avr5;@mmcu=avr5 avr51;@mmcu=avr51 avr6;@mmcu=avr6 avrxmega2;@mmcu=avrxmega2 avrxmega4;@mmcu=avrxmega4 avrxmega5;@mmcu=avrxmega5 avrxmega6;@mmcu=avrxmega6 avrxmega7;@mmcu=avrxmega7 tiny-stack;@msp8 avr25/tiny-stack;@mmcu=avr25@msp8 which is perfect and clean. As you can see, the multilib directory structure is /unchanged/ i.e. their names are still ./avr25/tiny-stack etc. Ok for trunk? Johann PR target/52737 * contrib/gcc_update (files_and_dependencies): Remove gcc/config/avr/t-multilib from touch data. gcc/ PR target/52737 * config.gcc (tm_file): Remove avr/multilib.h. * doc/invoke.texi (AVR Options): Adjust documentation of -mtiny-stack. * config/avr/genmultilib.awk: Remove code to generate multilib.h. (BEGIN): Use -msp8 as multilib option instead of -mtiny-stack. * config/avr/t-avr: Remove generation of multilib.h. * config/avr/t-multilib: Regenerate. * config/avr/multilib.h: Remove. * config/avr/avr.opt (-msp8): New option. (avr_sp8): New variable. * config/avr/driver-avr.c (avr_device_to_sp8): New function. * config/avr/avr.h (AVR_HAVE_SPH): New define. (AVR_HAVE_8BIT_SP): Also set by avr_sp8 i.e. -msp8. (avr_device_to_sp8): New prototype. (EXTRA_SPEC_FUNCTIONS): Add { "device_to_sp8", avr_device_to_sp8 } (DRIVER_SELF_SPECS): New define. * config/avr/avr-c.c (avr_cpu_cpp_builtins): New built-in defines: __AVR_SP8__, __AVR_HAVE_SPH__. * config/avr/avr.c (output_movhi): Use AVR_HAVE_SPH instead of AVR_HAVE_8BIT_SP to decide if SP_H is present. (avr_file_start): Ditto. libgcc/ PR target/52737 * config/avr/lib1funcs.S: Use __AVR_HAVE_SPH__ for SP_H checks instead of __AVR_HAVE_8BIT_SP__.
Index: contrib/gcc_update =================================================================== --- contrib/gcc_update (revision 185858) +++ contrib/gcc_update (working copy) @@ -83,7 +83,6 @@ gcc/config/arm/arm-tune.md: gcc/config/a gcc/config/arm/arm-tables.opt: gcc/config/arm/arm-arches.def gcc/config/arm/arm-cores.def gcc/config/arm/arm-fpus.def gcc/config/arm/genopt.sh gcc/config/avr/avr-tables.opt: gcc/config/avr/avr-mcus.def gcc/config/avr/genopt.sh gcc/config/avr/t-multilib: gcc/config/avr/avr-mcus.def gcc/config/avr/genmultilib.awk -gcc/config/avr/multilib.h: gcc/config/avr/avr-mcus.def gcc/config/avr/genmultilib.awk gcc/config/c6x/c6x-tables.opt: gcc/config/c6x/c6x-isas.def gcc/config/c6x/genopt.sh gcc/config/c6x/c6x-sched.md: gcc/config/c6x/c6x-sched.md.in gcc/config/c6x/gensched.sh gcc/config/c6x/c6x-mult.md: gcc/config/c6x/c6x-mult.md.in gcc/config/c6x/genmult.sh Index: gcc/config.gcc =================================================================== --- gcc/config.gcc (revision 185858) +++ gcc/config.gcc (working copy) @@ -898,13 +898,13 @@ arm*-wince-pe*) extra_objs="pe.o" ;; avr-*-rtems*) - tm_file="elfos.h avr/elf.h avr/avr.h avr/multilib.h dbxelf.h avr/rtems.h rtems.h newlib-stdint.h" + tm_file="elfos.h avr/elf.h avr/avr.h dbxelf.h avr/rtems.h rtems.h newlib-stdint.h" tmake_file="avr/t-avr avr/t-multilib t-rtems 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.h avr/multilib.h dbxelf.h newlib-stdint.h" + tm_file="elfos.h avr/elf.h avr/avr.h dbxelf.h newlib-stdint.h" tmake_file="avr/t-avr avr/t-multilib" use_gcc_stdint=wrap extra_gcc_objs="driver-avr.o avr-devices.o" Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 185858) +++ gcc/doc/invoke.texi (working copy) @@ -11131,8 +11131,7 @@ sbiw r26, const ; X -= const @item -mtiny-stack @opindex mtiny-stack -Only use the lower 8@tie{}bits of the stack pointer and assume that the high -byte of SP is always zero. +Only change the lower 8@tie{}bits of the stack pointer. @end table @subsubsection @code{EIND} and Devices with more than 128 Ki Bytes of Flash Index: libgcc/config/avr/lib1funcs.S =================================================================== --- libgcc/config/avr/lib1funcs.S (revision 185858) +++ libgcc/config/avr/lib1funcs.S (working copy) @@ -25,7 +25,9 @@ see the files COPYING3 and COPYING.RUNTI #define __zero_reg__ r1 #define __tmp_reg__ r0 #define __SREG__ 0x3f +#if defined (__AVR_HAVE_SPH__) #define __SP_H__ 0x3e +#endif #define __SP_L__ 0x3d #define __RAMPZ__ 0x3B #define __EIND__ 0x3C @@ -1258,7 +1260,7 @@ ENDF __divmodsi4 #if defined (__AVR_HAVE_JMP_CALL__) # define SPEED_DIV 8 -#elif defined (__AVR_HAVE_MOVW__) && !defined (__AVR_HAVE_8BIT_SP__) +#elif defined (__AVR_HAVE_MOVW__) && defined (__AVR_HAVE_SPH__) # define SPEED_DIV 16 #else # define SPEED_DIV 0 @@ -1540,10 +1542,10 @@ DEFUN __divdi3_moddi3 4: ;; Epilogue: Restore the Z = 12 Registers and return in r28, __SP_L__ -#if defined (__AVR_HAVE_8BIT_SP__) - clr r29 -#else +#if defined (__AVR_HAVE_SPH__) in r29, __SP_H__ +#else + clr r29 #endif /* #SP = 8/16 */ ldi r30, 12 XJMP __epilogue_restores__ + ((18 - 12) * 2) @@ -1691,7 +1693,7 @@ DEFUN __prologue_saves__ push r17 push r28 push r29 -#if defined (__AVR_HAVE_8BIT_SP__) +#if !defined (__AVR_HAVE_SPH__) in r28,__SP_L__ sub r28,r26 out __SP_L__,r28 @@ -1747,7 +1749,7 @@ DEFUN __epilogue_restores__ ldd r16,Y+4 ldd r17,Y+3 ldd r26,Y+2 -#if defined (__AVR_HAVE_8BIT_SP__) +#if !defined (__AVR_HAVE_SPH__) ldd r29,Y+1 add r28,r30 out __SP_L__,r28 Index: gcc/config/avr/t-multilib =================================================================== --- gcc/config/avr/t-multilib (revision 185858) +++ gcc/config/avr/t-multilib (working copy) @@ -21,57 +21,53 @@ # along with GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>. -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 mtiny-stack +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 msp8 MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack avr25/tiny-stack MULTILIB_EXCEPTIONS = \ - mmcu=avr3/mtiny-stack \ - mmcu=avr31/mtiny-stack \ - mmcu=avr35/mtiny-stack \ - mmcu=avr4/mtiny-stack \ - mmcu=avr5/mtiny-stack \ - mmcu=avr51/mtiny-stack \ - mmcu=avr6/mtiny-stack \ - mmcu=avrxmega2/mtiny-stack \ - mmcu=avrxmega4/mtiny-stack \ - mmcu=avrxmega5/mtiny-stack \ - mmcu=avrxmega6/mtiny-stack \ - mmcu=avrxmega7/mtiny-stack + 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 MULTILIB_MATCHES = \ - mmcu?at90s2313=mmcu?at90s2313 \ - mmcu?at90s2323=mmcu?at90s2323 \ - mmcu?at90s2333=mmcu?at90s2333 \ - mmcu?at90s2343=mmcu?at90s2343 \ - mmcu?attiny22=mmcu?attiny22 \ - mmcu?attiny26=mmcu?attiny26 \ - mmcu?at90s4433=mmcu?at90s4433 \ + mmcu?avr2=mmcu?at90s2313 \ + mmcu?avr2=mmcu?at90s2323 \ + mmcu?avr2=mmcu?at90s2333 \ + mmcu?avr2=mmcu?at90s2343 \ + mmcu?avr2=mmcu?attiny22 \ + mmcu?avr2=mmcu?attiny26 \ + mmcu?avr2=mmcu?at90s4414 \ + mmcu?avr2=mmcu?at90s4433 \ + mmcu?avr2=mmcu?at90s4434 \ + mmcu?avr2=mmcu?at90s8515 \ + mmcu?avr2=mmcu?at90c8534 \ + mmcu?avr2=mmcu?at90s8535 \ mmcu?avr25=mmcu?ata6289 \ - mmcu?attiny13=mmcu?attiny13 \ mmcu?avr25=mmcu?attiny13 \ - mmcu?attiny13a=mmcu?attiny13a \ mmcu?avr25=mmcu?attiny13a \ - mmcu?attiny2313=mmcu?attiny2313 \ mmcu?avr25=mmcu?attiny2313 \ - mmcu?attiny2313a=mmcu?attiny2313a \ mmcu?avr25=mmcu?attiny2313a \ - mmcu?attiny24=mmcu?attiny24 \ mmcu?avr25=mmcu?attiny24 \ - mmcu?attiny24a=mmcu?attiny24a \ mmcu?avr25=mmcu?attiny24a \ mmcu?avr25=mmcu?attiny4313 \ mmcu?avr25=mmcu?attiny44 \ mmcu?avr25=mmcu?attiny44a \ mmcu?avr25=mmcu?attiny84 \ mmcu?avr25=mmcu?attiny84a \ - mmcu?attiny25=mmcu?attiny25 \ mmcu?avr25=mmcu?attiny25 \ mmcu?avr25=mmcu?attiny45 \ mmcu?avr25=mmcu?attiny85 \ - mmcu?attiny261=mmcu?attiny261 \ mmcu?avr25=mmcu?attiny261 \ - mmcu?attiny261a=mmcu?attiny261a \ mmcu?avr25=mmcu?attiny261a \ mmcu?avr25=mmcu?attiny461 \ mmcu?avr25=mmcu?attiny461a \ Index: gcc/config/avr/avr.opt =================================================================== --- gcc/config/avr/avr.opt (revision 185858) +++ gcc/config/avr/avr.opt (working copy) @@ -73,3 +73,7 @@ Accumulate outgoing function arguments a mstrict-X Target Report Var(avr_strict_X) Init(0) When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register. Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X. + +;; For rationale behind -msp8 see explanation in avr.h. +msp8 +Target Report RejectNegative Undocumented Var(avr_sp8) Init(0) Index: gcc/config/avr/avr-c.c =================================================================== --- gcc/config/avr/avr-c.c (revision 185858) +++ gcc/config/avr/avr-c.c (working copy) @@ -128,6 +128,12 @@ avr_cpu_cpp_builtins (struct cpp_reader 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__"); + if (TARGET_NO_INTERRUPTS) cpp_define (pfile, "__NO_INTERRUPTS__"); Index: gcc/config/avr/t-avr =================================================================== --- gcc/config/avr/t-avr (revision 185858) +++ gcc/config/avr/t-avr (working copy) @@ -49,16 +49,10 @@ $(srcdir)/config/avr/avr-tables.opt: $(s # MULTILIB_MATCHES $(srcdir)/config/avr/t-multilib: s-avr-mlib; @true -# Override multilib_raw[] from multilib.h -$(srcdir)/config/avr/multilib.h: s-avr-mlib; @true - s-mlib: $(srcdir)/config/avr/t-multilib s-avr-mlib: $(srcdir)/config/avr/genmultilib.awk $(AVR_MCUS) $(AWK) -f $< -v FORMAT=Makefile $< $(AVR_MCUS) > tmp-avr-mlib - $(AWK) -f $< -v FORMAT=multilib.h $< $(AVR_MCUS) > tmp-avr-mlib.h - $(SHELL) $(srcdir)/../move-if-change \ - tmp-avr-mlib.h $(srcdir)/config/avr/multilib.h $(SHELL) $(srcdir)/../move-if-change \ tmp-avr-mlib $(srcdir)/config/avr/t-multilib $(STAMP) $@ Index: gcc/config/avr/genmultilib.awk =================================================================== --- gcc/config/avr/genmultilib.awk (revision 185858) +++ gcc/config/avr/genmultilib.awk (working copy) @@ -26,9 +26,6 @@ # FORMAT = "Makefile": Generate Makefile Snipet that sets some # MULTILIB_* Variables as needed. # -# FORMAT = "multilib.h": Generate C Header intended to override -# (parts of) multilib.h used in gcc.c. -# ################################################################## BEGIN { @@ -41,7 +38,7 @@ BEGIN { mtiny[0] = "" mtiny[1] = "tiny-stack" - option["tiny-stack"] = "mtiny-stack" + option["tiny-stack"] = "msp8" } ################################################################## @@ -54,18 +51,6 @@ BEGIN { next else if (comment == 1) { - if (FORMAT == "multilib.h") - { - print "/*" - print " Auto-generated C header" - print " Generated by : ./gcc/config/avr/genmultilib.awk" - print " Generated from : ./gcc/config/avr/avr-mcus.def" - print " Used by : ./gcc/gcc.c via tm.h" - print " Purpose : Override multilib_raw[] from multilib.h" - print "*/" - print "/*" - } - if (FORMAT == "Makefile") { print "# Auto-generated Makefile Snip" @@ -78,15 +63,12 @@ BEGIN { comment = 2; - if (FORMAT == "multilib.h") - gsub ("#", " ") - print } /^$/ { - if (comment && FORMAT == "multilib.h") - print "*/" + # The first empty line stops copy-pasting the GPL comments + # from this file to the generated file. comment = 0 } @@ -144,7 +126,6 @@ BEGIN { # m_dirnames <-> MULTILIB_DIRNAMES " # m_exceptions <-> MULTILIB_EXCEPTIONS " # m_matches <-> MULTILIB_MATCHES " -# m_raw <-> avr_multilib_raw multilib.h # ################################################################## @@ -154,11 +135,9 @@ END { m_exceptions = "\nMULTILIB_EXCEPTIONS =" m_matches = "\nMULTILIB_MATCHES =" - m_raw = "" - ############################################################## # Compose MULTILIB_OPTIONS. This represents the Cross-Product - # (avr2, avr25, ...) x mtiny-stack + # (avr2, avr25, ...) x msp8 sep = "" for (c = 0; c < n_cores; c++) @@ -167,54 +146,25 @@ END { sep = "/" } - # The ... x mtiny-stack + # The ... x msp8 m_options = m_options " " option[mtiny[1]] ############################################################## # Map Device to its multilib - # All Mappings that cannot be represented by GCC's genmultilib - # Machinery must be handcrafted. - - dot_excludes = "" - m_raw_sp8 = "" - for (t = 0; t < n_mcu; t++) { core = toCore[mcu[t]] - if (tiny_stack[mcu[t]] == 1) - { - if (core == "avr2") - dir = mtiny[1] - else - dir = core "/" mtiny[1] - - m_raw_sp8 = m_raw_sp8 " \"" dir " " option[mcu[t]] ";\",\n" - dot_excludes = dot_excludes " !" option[mcu[t]] - - line = option[mcu[t]] ":" option[mcu[t]] - gsub ("=", "?", line) - gsub (":", "=", line) - - m_matches = m_matches " \\\n\t" line - } - - # The SP = 16 Devices are vanilla: Do the same as - # MULTILIB_MATCHES would yield. Don't list avr2 (default) - - if (core != "avr2") - { - line = option[core] ":" option[mcu[t]] - gsub ("=", "?", line) - gsub (":", "=", line) + line = option[core] ":" option[mcu[t]] + gsub ("=", "?", line) + gsub (":", "=", line) - m_matches = m_matches " \\\n\t" line - } + m_matches = m_matches " \\\n\t" line } #################################################################### - # Compose MULTILIB_DIRNAMES, MULTILIB_EXEPTIONS and avr_multilib_raw + # Compose MULTILIB_DIRNAMES and MULTILIB_EXEPTIONS n_mtiny = 2 for (t = 0; t < n_mtiny; t++) @@ -248,38 +198,6 @@ END { if (core != "avr2" || mtiny[t] == "") m_dirnames = m_dirnames " " mdir - - # Remainder deals with avr_multilib_raw Entries. - # Each Entry looks like - # "multilib-dir option-to-match !option-to-avoid-match;" - # for Example: - # "avr25/tiny-stack !mmcu=avr2 mmcu=avr25 !mmcu=avr3 ... mtiny-stack;" - - if (mdir == "") - mdir = "." - - line = mdir - - for (s = 0; s < n_cores; s++) - { - if (cores[s] == core) - line = line " " option[cores[s]] - else - line = line " !" option[cores[s]] - } - - if (tiny_stack[core] != 0) - { - if (mtiny[t] == "") - line = line " !" option[mtiny[1]] - else - line = line " " option[mtiny[1]] - } - - if (mdir == ".") - line = line dot_excludes - - m_raw = m_raw " \"" line ";\",\n" } ############################################################ @@ -295,21 +213,4 @@ END { print m_exceptions print m_matches } - - if (FORMAT == "multilib.h") - { - # Intended Target: ./gcc/config/avr/multilib.h - - print "#if defined NULL && !defined AVR_MULTILIB_H" - print "#define AVR_MULTILIB_H" - - print "static const char* const avr_multilib_raw[] = {" - print m_raw_sp8 - print m_raw - print " NULL\n};" - - print "#undef multilib_raw" - print "#define multilib_raw avr_multilib_raw" - print "#endif /* AVR_MULTILIB_H */" - } } Index: gcc/config/avr/driver-avr.c =================================================================== --- gcc/config/avr/driver-avr.c (revision 185858) +++ gcc/config/avr/driver-avr.c (working copy) @@ -112,3 +112,24 @@ avr_device_to_devicelib (int argc, const return concat ("-l", avr_current_device->library_name, NULL); } +const char* +avr_device_to_sp8 (int argc, const char **argv) +{ + if (0 == argc) + return NULL; + + avr_set_current_device (argv[0]); + + /* Leave "avr2" and "avr25" alone. These two architectures are + the only ones that mix devices with 8-bit SP and 16-bit SP. + -msp8 is set by mmultilib machinery. */ + + if (avr_current_device->macro == NULL + && (avr_current_device->arch == ARCH_AVR2 + || avr_current_device->arch == ARCH_AVR25)) + return ""; + + return avr_current_device->short_sp + ? "-msp8" + : "%<msp8"; +} Index: gcc/config/avr/multilib.h =================================================================== --- gcc/config/avr/multilib.h (revision 185858) +++ gcc/config/avr/multilib.h (working copy) @@ -1,70 +0,0 @@ -/* - Auto-generated C header - Generated by : ./gcc/config/avr/genmultilib.awk - Generated from : ./gcc/config/avr/avr-mcus.def - Used by : ./gcc/gcc.c via tm.h - Purpose : Override multilib_raw[] from multilib.h -*/ -/* - Copyright (C) 2011 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/>. -*/ -#if defined NULL && !defined AVR_MULTILIB_H -#define AVR_MULTILIB_H -static const char* const avr_multilib_raw[] = { - "tiny-stack mmcu=at90s2313;", - "tiny-stack mmcu=at90s2323;", - "tiny-stack mmcu=at90s2333;", - "tiny-stack mmcu=at90s2343;", - "tiny-stack mmcu=attiny22;", - "tiny-stack mmcu=attiny26;", - "tiny-stack mmcu=at90s4433;", - "avr25/tiny-stack mmcu=attiny13;", - "avr25/tiny-stack mmcu=attiny13a;", - "avr25/tiny-stack mmcu=attiny2313;", - "avr25/tiny-stack mmcu=attiny2313a;", - "avr25/tiny-stack mmcu=attiny24;", - "avr25/tiny-stack mmcu=attiny24a;", - "avr25/tiny-stack mmcu=attiny25;", - "avr25/tiny-stack mmcu=attiny261;", - "avr25/tiny-stack mmcu=attiny261a;", - - ". !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 !mtiny-stack !mmcu=at90s2313 !mmcu=at90s2323 !mmcu=at90s2333 !mmcu=at90s2343 !mmcu=attiny22 !mmcu=attiny26 !mmcu=at90s4433 !mmcu=attiny13 !mmcu=attiny13a !mmcu=attiny2313 !mmcu=attiny2313a !mmcu=attiny24 !mmcu=attiny24a !mmcu=attiny25 !mmcu=attiny261 !mmcu=attiny261a;", - "avr2 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 !mtiny-stack;", - "avr25 !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 !mtiny-stack;", - "avr3 !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;", - "avr31 !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;", - "avr35 !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;", - "avr4 !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;", - "avr5 !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;", - "avr51 !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;", - "avr6 !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;", - "avrxmega2 !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;", - "avrxmega4 !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;", - "avrxmega5 !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;", - "avrxmega6 !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;", - "avrxmega7 !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;", - "tiny-stack !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 mtiny-stack;", - "avr2/tiny-stack 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 mtiny-stack;", - "avr25/tiny-stack !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 mtiny-stack;", - - NULL -}; -#undef multilib_raw -#define multilib_raw avr_multilib_raw -#endif /* AVR_MULTILIB_H */ Index: gcc/config/avr/avr.c =================================================================== --- gcc/config/avr/avr.c (revision 185858) +++ gcc/config/avr/avr.c (working copy) @@ -963,7 +963,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT { /* Don't error so that insane code from newlib still compiles and does not break building newlib. As PR51345 is implemented - now, there are multilib variants with -mtiny-stack. + now, there are multilib variants with -msp8. If user wants sanity checks he can use -Wstack-usage= or similar options. @@ -2774,7 +2774,7 @@ output_movhi (rtx insn, rtx xop[], int * } else if (test_hard_reg_class (STACK_REG, src)) { - return AVR_HAVE_8BIT_SP + return !AVR_HAVE_SPH ? avr_asm_len ("in %A0,__SP_L__" CR_TAB "clr %B0", xop, plen, -2) @@ -7341,7 +7341,7 @@ avr_file_start (void) /* Print I/O addresses of some SFRs used with IN and OUT. */ - if (!AVR_HAVE_8BIT_SP) + if (AVR_HAVE_SPH) fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset); fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset); Index: gcc/config/avr/avr.h =================================================================== --- gcc/config/avr/avr.h (revision 185858) +++ gcc/config/avr/avr.h (working copy) @@ -188,7 +188,26 @@ enum #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_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK) + +/* Handling of 8-bit SP versus 16-bit SP is as follows: + + -msp8 is used internally to select the right multilib for targets with + 8-bit SP. -msp8 is set automatically by DRIVER_SELF_SPECS for devices + with 8-bit SP or by multilib generation machinery. If a frame pointer is + needed and SP is only 8 bits wide, SP is zero-extended to get FP. + + TARGET_TINY_STACK is triggered by -mtiny-stack which is a user option. + This option has no effect on multilib selection. It serves to save some + bytes on 16-bit SP devices by only changing SP_L and leaving SP_H alone. + + These two properties are reflected by built-in macros __AVR_SP8__ resp. + __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->short_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) @@ -577,13 +596,16 @@ extern const char *avr_device_to_arch (i extern const char *avr_device_to_data_start (int argc, const char **argv); extern const char *avr_device_to_startfiles (int argc, const char **argv); extern const char *avr_device_to_devicelib (int argc, const char **argv); +extern const char *avr_device_to_sp8 (int argc, const char **argv); -#define EXTRA_SPEC_FUNCTIONS \ - { "device_to_arch", avr_device_to_arch }, \ +#define EXTRA_SPEC_FUNCTIONS \ + { "device_to_arch", avr_device_to_arch }, \ { "device_to_data_start", avr_device_to_data_start }, \ - { "device_to_startfile", avr_device_to_startfiles }, \ - { "device_to_devicelib", avr_device_to_devicelib }, + { "device_to_startfile", avr_device_to_startfiles }, \ + { "device_to_devicelib", avr_device_to_devicelib }, \ + { "device_to_sp8", avr_device_to_sp8 }, +#define DRIVER_SELF_SPECS " %:device_to_sp8(%{mmcu=*:%*}) " #define CPP_SPEC "" #define CC1_SPEC ""