From patchwork Thu Jun 16 07:27:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Senthil Kumar Selvaraj X-Patchwork-Id: 636242 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rVZk10HwFz9t0c for ; Thu, 16 Jun 2016 17:28:24 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=htNibXzh; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :references:from:to:cc:subject:in-reply-to:date:message-id :mime-version:content-type; q=dns; s=default; b=FfndUjKHejqYRz0+ FYYjEzv3iAJp1iWHyTtUGhcUSkBNVyANtmMLIH5stLTehAL5pjv3C3y7anyO22KH OqsKMqyygGLHM9TuPog02I6G5I4BoYxY/9Qnty4d8XZOcvYBhgD/SiVqdQ0JZkQl KBuGNJnEGBQDUFWcAcSi7oSMZeg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :references:from:to:cc:subject:in-reply-to:date:message-id :mime-version:content-type; s=default; bh=95wEcZNV5E6k/V5tODwd24 9lzjs=; b=htNibXzh7/E320y3fWB9Y8/OSFMOkDcV1IzewGY7Idp+JasiY85tOu jnFfUUB5pO+RRITbcvD7bnKdNVP1BdSweV8+evqknvylSEjstSkcBNj0pGTk8+g9 RcWNaSgE4TbW2se7FZ9hZ/rjgKK/wriO89qCvEEk4uuooBuL4Wt0w= Received: (qmail 41627 invoked by alias); 16 Jun 2016 07:28:15 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 40656 invoked by uid 89); 16 Jun 2016 07:28:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=pools, __memx, resulted, incorporating X-HELO: eusmtp01.atmel.com Received: from eusmtp01.atmel.com (HELO eusmtp01.atmel.com) (212.144.249.242) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 16 Jun 2016 07:28:04 +0000 Received: from HNOCHT01.corp.atmel.com (10.161.30.161) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server (TLS) id 14.3.235.1; Thu, 16 Jun 2016 09:27:54 +0200 Received: from jaguar.atmel.com (10.161.30.18) by HNOCHT01.corp.atmel.com (10.161.30.161) with Microsoft SMTP Server (TLS) id 14.3.235.1; Thu, 16 Jun 2016 09:27:56 +0200 References: <87y46m1h3y.fsf@atmel.com> <5751B5EA.5000108@gjlay.de> <877fe1nrdy.fsf@atmel.com> User-agent: mu4e 0.9.17; emacs 24.5.1 From: Senthil Kumar Selvaraj To: Georg-Johann Lay CC: , Denis Chertykov Subject: Re: [Patch, avr] Fix PR 71151 In-Reply-To: <877fe1nrdy.fsf@atmel.com> Date: Thu, 16 Jun 2016 12:57:40 +0530 Message-ID: <87lh258ufn.fsf@atmel.com> MIME-Version: 1.0 X-IsSubscribed: yes Senthil Kumar Selvaraj writes: > Georg-Johann Lay writes: > >> Senthil Kumar Selvaraj schrieb: >>> Hi, >>> >>> This patch fixes PR 71151 by eliminating the >>> TARGET_ASM_FUNCTION_RODATA_SECTION hook and setting >>> JUMP_TABLES_IN_TEXT_SECTION to 1. >>> >>> As described in the bugzilla entry, this hook assumed it will get >>> called only for jumptable rodata for functions. This was true until >>> 6.1, when a commit in varasm.c started calling the hook for mergeable >>> string/constant data as well. >>> >>> This resulted in string constants ending up in a section intended for >>> jumptables (flash), and broke code using those constants, which >>> expects them to be present in rodata (SRAM). >>> >>> Given that the original reason for placing jumptables in a section was >>> fixed by Johann in PR 63323, this patch restores the original >>> behavior. Reg testing on both gcc-6-branch and trunk showed no regressions. >> >> Just for the record: >> >> The intention for jump-tables in function-rodata-section was to get >> fine-grained section for the tables so that --gc-sections and >> -ffunction-sections not only gc unused functions but also unused >> jump-tables. As these tables had to reside in the lowest 64KiB of flash >> (.progmem section) neither .rodata nor .text was a correct placement, >> hence the hacking in TARGET_ASM_FUNCTION_RODATA_SECTION. >> >> Before using TARGET_ASM_FUNCTION_RODATA_SECTION, all jump tables were >> put into .progmem.gcc_sw_table by ASM_OUTPUT_BEFORE_CASE_LABEL switching >> to that section. >> >> We actually never had fump-tables in .text before... > > JUMP_TABLES_IN_TEXT_SECTION was 1 before r37465 - that was when the > progmem.gcc_sw_table section was introduced. But yes, I understand that > the target hook for FUNCTION_RODATA_SECTION was done to get them gc'ed > along with the code. > >> >> The purpose of PR63323 was to have more generic jump-table >> implementation that also works if the table does NOT reside in the lower >> 64KiB. This happens when moving whole whole TEXT section around like >> for a bootloader. > > Understood. >> >>> As pointed out by Johann, this may end up increasing code >>> size if there are lots of branches that cross the jump tables. I >>> intend to propose a separate patch that gives additional information >>> to the target hook (SECCAT_RODATA_{STRING,JUMPTABLE}) so it can know >>> what type of function rodata is coming on. Johann also suggested >>> handling jump table generation ourselves - I'll experiment with that >>> some more. >>> >>> If ok, could someone commit please? Could you also backport to >>> gcc-6-branch? >>> >>> Regards >>> Senthil >>> >>> gcc/ChangeLog >>> >>> 2016-06-03 Senthil Kumar Selvaraj >>> >>> * config/avr/avr.c (avr_asm_function_rodata_section): Remove. >>> * config/avr/avr.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Remove. >>> >>> gcc/testsuite/ChangeLog >>> >>> 2016-06-03 Senthil Kumar Selvaraj >>> >>> * gcc/testsuite/gcc.target/avr/pr71151-1.c: New. >>> * gcc/testsuite/gcc.target/avr/pr71151-2.c: New. >>> >>> diff --git gcc/config/avr/avr.c gcc/config/avr/avr.c >>> index ba5cd91..3cb8cb7 100644 >>> --- gcc/config/avr/avr.c >>> +++ gcc/config/avr/avr.c >>> @@ -9488,65 +9488,6 @@ avr_asm_init_sections (void) >>> } >>> >>> >>> -/* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'. */ >>> - >>> -static section* >>> -avr_asm_function_rodata_section (tree decl) >>> -{ >>> - /* If a function is unused and optimized out by -ffunction-sections >>> - and --gc-sections, ensure that the same will happen for its jump >>> - tables by putting them into individual sections. */ >>> - >>> - unsigned int flags; >>> - section * frodata; >>> - >>> - /* Get the frodata section from the default function in varasm.c >>> - but treat function-associated data-like jump tables as code >>> - rather than as user defined data. AVR has no constant pools. */ >>> - { >>> - int fdata = flag_data_sections; >>> - >>> - flag_data_sections = flag_function_sections; >>> - frodata = default_function_rodata_section (decl); >>> - flag_data_sections = fdata; >>> - flags = frodata->common.flags; >>> - } >>> - >>> - if (frodata != readonly_data_section >>> - && flags & SECTION_NAMED) >>> - { >>> - /* Adjust section flags and replace section name prefix. */ >>> - >>> - unsigned int i; >>> - >>> - static const char* const prefix[] = >>> - { >>> - ".rodata", ".progmem.gcc_sw_table", >>> - ".gnu.linkonce.r.", ".gnu.linkonce.t." >>> - }; >>> - >>> - for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2) >>> - { >>> - const char * old_prefix = prefix[i]; >>> - const char * new_prefix = prefix[i+1]; >>> - const char * name = frodata->named.name; >>> - >>> - if (STR_PREFIX_P (name, old_prefix)) >>> - { >>> - const char *rname = ACONCAT ((new_prefix, >>> - name + strlen (old_prefix), NULL)); >>> - flags &= ~SECTION_CODE; >>> - flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE; >>> - >>> - return get_section (rname, flags, frodata->named.decl); >>> - } >>> - } >>> - } >>> - >>> - return progmem_swtable_section; >>> -} >>> - >>> - >>> /* Implement `TARGET_ASM_NAMED_SECTION'. */ >>> /* Track need of __do_clear_bss, __do_copy_data for named sections. */ >>> >>> @@ -13747,9 +13688,6 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg, >>> #undef TARGET_FOLD_BUILTIN >>> #define TARGET_FOLD_BUILTIN avr_fold_builtin >>> >>> -#undef TARGET_ASM_FUNCTION_RODATA_SECTION >>> -#define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section >>> - >>> #undef TARGET_SCALAR_MODE_SUPPORTED_P >>> #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p >>> >>> diff --git gcc/config/avr/avr.h gcc/config/avr/avr.h >>> index 01da708..ab5e465 100644 >>> --- gcc/config/avr/avr.h >>> +++ gcc/config/avr/avr.h >>> @@ -391,7 +391,7 @@ typedef struct avr_args >>> >>> #define SUPPORTS_INIT_PRIORITY 0 >>> >>> -#define JUMP_TABLES_IN_TEXT_SECTION 0 >>> +#define JUMP_TABLES_IN_TEXT_SECTION 1 >> >> IMO the simplest approach as a quick fix. >> >>> >>> #define ASM_COMMENT_START " ; " >>> >>> diff --git gcc/testsuite/gcc.target/avr/pr71151-1.c gcc/testsuite/gcc.target/avr/pr71151-1.c >>> new file mode 100644 >>> index 0000000..615dce8 >>> --- /dev/null >>> +++ gcc/testsuite/gcc.target/avr/pr71151-1.c >>> @@ -0,0 +1,12 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-Os -ffunction-sections -fdata-sections" } */ >>> + >>> +/* { dg-final { scan-assembler-not ".section .progmem.gcc_sw_table.foo.str1.1" } } */ >>> +/* { dg-final { scan-assembler ".section .rodata.foo.str1.1,\"aMS\"" } } */ >>> + >>> + >>> +extern void bar(const char*); >>> +void foo(void) >>> +{ >>> + bar("BBBBBBBBBB"); >>> +} >>> diff --git gcc/testsuite/gcc.target/avr/pr71151-2.c gcc/testsuite/gcc.target/avr/pr71151-2.c >>> new file mode 100644 >>> index 0000000..0041858 >>> --- /dev/null >>> +++ gcc/testsuite/gcc.target/avr/pr71151-2.c >>> @@ -0,0 +1,49 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-Os -ffunction-sections -fdata-sections" } */ >>> + >>> +/* Make sure jumptables work properly, after removing the >>> + special section placement hook. */ >>> + >>> +#include "exit-abort.h" >>> + >>> +volatile char y; >>> +volatile char g; >>> + >>> +void foo(char x) >>> +{ >>> + switch (x) >>> + { >>> + case 0: >>> + y = 67; break; >>> + case 1: >>> + y = 20; break; >>> + case 2: >>> + y = 109; break; >>> + case 3: >>> + y = 33; break; >>> + case 4: >>> + y = 44; break; >>> + case 5: >>> + y = 37; break; >>> + case 6: >>> + y = 10; break; >>> + case 7: >>> + y = 98; break; >>> + } >> >> Not sure if this actually generates a jump-table and not a look-up from >> .rodata by means of tree-switch-conversion. Hence consider >> -fno-tree-switch-conversion. > > It did generate a jumptable, but I added -fno-tree-switch-conversion > just in case. >> >> The interesting cases are: >> >> - jump-table does not reside in the lower 64KiB >> >> - jump-table crosses a 64KiB boundary (RAMPZ increments) >> >> - jump-table needs linker stub generation, i.e. resides in > 128KiB >> >> IICR there is special code in the linker that avoids relaxing for some >> sections by means of magic name section names? > > Yes, for ".vectors" and ".jumptables". > > I added tests that use linker relaxation and discovered arelaxation bug > in binutils 2.26 (and later) that messes up symbol values in the > presence of alignment directives. I'm working on that right now - > hopefully, it'll get backported to the release branch. > > Once that gets upstream, I'll resend the patch - with more tests, and > incorporating your comments. > There were two binutils bugs (PR ld/20221 and ld/20254) that were blocking this patch - on enabling, relaxation, jumptables were getting corrupted. Both of the issues are now fixed, and the fixes are in master and 2.26 branch. This is pretty much the same patch as before, but with a lot more testcases as suggested by Johann, testing jumptables above 64K, straddling 128K, and above 128K, with and without relaxation. All the tests pass with atxmega128. For atmega128, the tests that place code above 128K fail (because the avrtest rightly ABORTs on excess flash size), the other tests pass. Perhaps we need a dg-require for large flash devices? If this is ok, could someone commit please? I don't have commit access. Regards Senthil gcc/ChangeLog: 2016-06-16 Senthil Kumar Selvaraj * config/avr/avr.c (avr_asm_init_sections): Remove setup of progmem_swtable_section. (progmem_swtable_section): Remove. (avr_asm_function_rodata_section): Remove. (TARGET_ASM_FUNCTION_RODATA_SECTION): Remove. * config/avr/avr.h (JUMP_TABLES_IN_TEXT_SECTION: Define to 1. gcc/testsuite/ChangeLog: 2016-06-16 Senthil Kumar Selvaraj * gcc.target/avr/pr71151-1.c: New test. * gcc.target/avr/pr71151-2.c: New test. * gcc.target/avr/pr71151-3.c: New test. * gcc.target/avr/pr71151-4.c: New test. * gcc.target/avr/pr71151-5.c: New test. * gcc.target/avr/pr71151-6.c: New test. * gcc.target/avr/pr71151-7.c: New test. * gcc.target/avr/pr71151-8.c: New test. * gcc.target/avr/pr71151-common.h: New test. diff --git gcc/config/avr/avr.c gcc/config/avr/avr.c index ba5cd91..dd99f42 100644 --- gcc/config/avr/avr.c +++ gcc/config/avr/avr.c @@ -203,9 +203,6 @@ static GTY(()) rtx xstring_e; /* Current architecture. */ const avr_arch_t *avr_arch; -/* Section to put switch tables in. */ -static GTY(()) section *progmem_swtable_section; - /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM or to address space __flash* or __memx. Only used as singletons inside avr_asm_select_section, but it must not be local there because of GTY. */ @@ -9461,24 +9458,6 @@ avr_output_progmem_section_asm_op (const void *data) static void avr_asm_init_sections (void) { - /* Set up a section for jump tables. Alignment is handled by - ASM_OUTPUT_BEFORE_CASE_LABEL. */ - - if (AVR_HAVE_JMP_CALL) - { - progmem_swtable_section - = get_unnamed_section (0, output_section_asm_op, - "\t.section\t.progmem.gcc_sw_table" - ",\"a\",@progbits"); - } - else - { - progmem_swtable_section - = get_unnamed_section (SECTION_CODE, output_section_asm_op, - "\t.section\t.progmem.gcc_sw_table" - ",\"ax\",@progbits"); - } - /* Override section callbacks to keep track of `avr_need_clear_bss_p' resp. `avr_need_copy_data_p'. */ @@ -9488,65 +9467,6 @@ avr_asm_init_sections (void) } -/* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'. */ - -static section* -avr_asm_function_rodata_section (tree decl) -{ - /* If a function is unused and optimized out by -ffunction-sections - and --gc-sections, ensure that the same will happen for its jump - tables by putting them into individual sections. */ - - unsigned int flags; - section * frodata; - - /* Get the frodata section from the default function in varasm.c - but treat function-associated data-like jump tables as code - rather than as user defined data. AVR has no constant pools. */ - { - int fdata = flag_data_sections; - - flag_data_sections = flag_function_sections; - frodata = default_function_rodata_section (decl); - flag_data_sections = fdata; - flags = frodata->common.flags; - } - - if (frodata != readonly_data_section - && flags & SECTION_NAMED) - { - /* Adjust section flags and replace section name prefix. */ - - unsigned int i; - - static const char* const prefix[] = - { - ".rodata", ".progmem.gcc_sw_table", - ".gnu.linkonce.r.", ".gnu.linkonce.t." - }; - - for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2) - { - const char * old_prefix = prefix[i]; - const char * new_prefix = prefix[i+1]; - const char * name = frodata->named.name; - - if (STR_PREFIX_P (name, old_prefix)) - { - const char *rname = ACONCAT ((new_prefix, - name + strlen (old_prefix), NULL)); - flags &= ~SECTION_CODE; - flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE; - - return get_section (rname, flags, frodata->named.decl); - } - } - } - - return progmem_swtable_section; -} - - /* Implement `TARGET_ASM_NAMED_SECTION'. */ /* Track need of __do_clear_bss, __do_copy_data for named sections. */ @@ -13747,9 +13667,6 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg, #undef TARGET_FOLD_BUILTIN #define TARGET_FOLD_BUILTIN avr_fold_builtin -#undef TARGET_ASM_FUNCTION_RODATA_SECTION -#define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section - #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p diff --git gcc/config/avr/avr.h gcc/config/avr/avr.h index 01da708..ab5e465 100644 --- gcc/config/avr/avr.h +++ gcc/config/avr/avr.h @@ -391,7 +391,7 @@ typedef struct avr_args #define SUPPORTS_INIT_PRIORITY 0 -#define JUMP_TABLES_IN_TEXT_SECTION 0 +#define JUMP_TABLES_IN_TEXT_SECTION 1 #define ASM_COMMENT_START " ; " diff --git gcc/testsuite/gcc.target/avr/pr71151-1.c gcc/testsuite/gcc.target/avr/pr71151-1.c new file mode 100644 index 0000000..615dce8 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -ffunction-sections -fdata-sections" } */ + +/* { dg-final { scan-assembler-not ".section .progmem.gcc_sw_table.foo.str1.1" } } */ +/* { dg-final { scan-assembler ".section .rodata.foo.str1.1,\"aMS\"" } } */ + + +extern void bar(const char*); +void foo(void) +{ + bar("BBBBBBBBBB"); +} diff --git gcc/testsuite/gcc.target/avr/pr71151-2.c gcc/testsuite/gcc.target/avr/pr71151-2.c new file mode 100644 index 0000000..e523ce0 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-2.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion -ffunction-sections -fdata-sections" } */ + +/* Make sure jumptables work properly if placed below 64 KB i.e. 2 byte + flash address for loading jump table entry, 2 byte entry, after + removing the special section placement hook. */ + +#include "exit-abort.h" +#include "pr71151-common.h" + +int main() +{ + foo(5); + if (y != 37) + abort(); + + foo(0); + if (y != 67) + abort(); + + foo(7); + if (y != 98) + abort(); +} diff --git gcc/testsuite/gcc.target/avr/pr71151-3.c gcc/testsuite/gcc.target/avr/pr71151-3.c new file mode 100644 index 0000000..ce0ba59 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-3.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion -ffunction-sections -mno-relax -fdata-sections -Wl,--section-start=.foo=0x10000" } */ + +/* Make sure jumptables work properly if placed above 64 KB and below 128 KB, + i.e. 3 byte flash address for loading jump table entry and 2 byte jump table + entry, with relaxation disabled, after removing the special section + placement hook. */ + +#include "exit-abort.h" +#include "pr71151-common.h" + +int main() +{ + foo(5); + if (y != 37) + abort(); + + foo(0); + if (y != 67) + abort(); + + foo(7); + if (y != 98) + abort(); +} diff --git gcc/testsuite/gcc.target/avr/pr71151-4.c gcc/testsuite/gcc.target/avr/pr71151-4.c new file mode 100644 index 0000000..51250b0 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-4.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion -ffunction-sections -fdata-sections -mrelax -Wl,--section-start=.foo=0x10000" } */ + +/* Make sure jumptables work properly if placed above 64 KB and below 128 KB, + i.e. 3 byte flash address for loading jump table entry and 2 byte jump + table entry, with relaxation enabled, after removing the special section + placement hook. */ + +#include "exit-abort.h" +#include "pr71151-common.h" + +int main() +{ + foo(5); + if (y != 37) + abort(); + + foo(0); + if (y != 67) + abort(); + + foo(7); + if (y != 98) + abort(); +} diff --git gcc/testsuite/gcc.target/avr/pr71151-5.c gcc/testsuite/gcc.target/avr/pr71151-5.c new file mode 100644 index 0000000..40fdb22 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-5.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion -ffunction-sections -fdata-sections -mno-relax -Wl,--section-start=.foo=0x20000" } */ + +/* Make sure jumptables work properly if placed above 128 KB, i.e. 3 byte + flash address for loading jump table entry and a jump table entry + that is a stub, with relaxation disabled, after removing the special + section placement hook. */ + +#include "exit-abort.h" +#include "pr71151-common.h" + +int main() +{ + /* Not meant for devices with flash <= 128K */ +#if defined (__AVR_2_BYTE_PC__) + exit(0); +#else + foo(5); + if (y != 37) + abort(); + + foo(0); + if (y != 67) + abort(); + + foo(7); + if (y != 98) + abort(); +#endif +} diff --git gcc/testsuite/gcc.target/avr/pr71151-6.c gcc/testsuite/gcc.target/avr/pr71151-6.c new file mode 100644 index 0000000..f4d2ef9 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-6.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion -ffunction-sections -fdata-sections -mrelax -Wl,--section-start=.foo=0x20000" } */ + +/* Make sure jumptables work properly if placed above 128 KB, i.e. 3 byte + flash address for loading jump table entry and a jump table entry + that is a stub, with relaxation enabled, after removing the special + section placement hook. */ + +#include "exit-abort.h" +#include "pr71151-common.h" + +int main() +{ + /* Not meant for devices with flash <= 128K */ +#if defined (__AVR_2_BYTE_PC__) + exit(0); +#else + foo(5); + if (y != 37) + abort(); + + foo(0); + if (y != 67) + abort(); + + foo(7); + if (y != 98) + abort(); +#endif +} diff --git gcc/testsuite/gcc.target/avr/pr71151-7.c gcc/testsuite/gcc.target/avr/pr71151-7.c new file mode 100644 index 0000000..cdc7ea9 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-7.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion -ffunction-sections -fdata-sections -mno-relax -Wl,--section-start=.foo=0x1fffa" } */ + +/* Make sure jumptables work properly if placed straddling 128 KB i.e + some entries below 128 KB and some above it, with relaxation disabled. */ + +#include "exit-abort.h" +#include "pr71151-common.h" + +int main() +{ + /* Not meant for devices with flash <= 128K */ +#if defined (__AVR_2_BYTE_PC__) + exit(0); +#else + foo(5); + if (y != 37) + abort(); + + foo(0); + if (y != 67) + abort(); + + foo(7); + if (y != 98) + abort(); +#endif +} diff --git gcc/testsuite/gcc.target/avr/pr71151-8.c gcc/testsuite/gcc.target/avr/pr71151-8.c new file mode 100644 index 0000000..0b7bf6a --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-8.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion -ffunction-sections -fdata-sections -mrelax -Wl,--section-start=.foo=0x1fffa" } */ + +/* Make sure jumptables work properly if placed straddling 128 KB i.e + some entries below 128 KB and some above it, with relaxation disabled. */ + +#include "exit-abort.h" +#include "pr71151-common.h" + +int main() +{ + /* Not meant for devices with flash <= 128K */ +#if defined (__AVR_2_BYTE_PC__) + exit(0); +#else + foo(5); + if (y != 37) + abort(); + + foo(0); + if (y != 67) + abort(); + + foo(7); + if (y != 98) + abort(); +#endif +} diff --git gcc/testsuite/gcc.target/avr/pr71151-common.h gcc/testsuite/gcc.target/avr/pr71151-common.h new file mode 100644 index 0000000..0df1783 --- /dev/null +++ gcc/testsuite/gcc.target/avr/pr71151-common.h @@ -0,0 +1,27 @@ +volatile char y; +volatile char g; + +__attribute__((section(".foo"))) +void foo(char x) +{ + switch (x) + { + case 0: + y = 67; break; + case 1: + y = 20; break; + case 2: + y = 109; break; + case 3: + y = 33; break; + case 4: + y = 44; break; + case 5: + y = 37; break; + case 6: + y = 10; break; + case 7: + y = 98; break; + } + y = y + g; +}