diff options
author | gjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-06-20 11:01:13 +0000 |
---|---|---|
committer | gjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-06-20 11:01:13 +0000 |
commit | ed7f4748cc6372f29d75740df96fece1227015b3 (patch) | |
tree | 4c3a3af841da295d3f4fb905197d8fc23e0599e5 | |
parent | 12dd7167f46367c543998a8b425692070b91d205 (diff) | |
download | gcc-ed7f4748cc6372f29d75740df96fece1227015b3.tar.gz |
gcc/
PR target/71103
* config/avr/avr.md (movqi): Handle loading subreg:qi (const).
gcc/testsuite/
PR target/71103
* gcc.target/avr/torture/pr71103-2.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237589 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr71103-2.c | 118 |
4 files changed, 143 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7d89449e22..2edfda0c7ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2016-06-20 Georg-Johann Lay <avr@gjlay.de> + PR target/71103 + * config/avr/avr.md (movqi): Handle loading subreg:qi (const). + +2016-06-20 Georg-Johann Lay <avr@gjlay.de> + * config/avr/avr.c (avr_print_operand): Fix "format not a string literal" build warnings. (avr_print_operand_address): Dito. diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 927bc6967a1..aac830154f0 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -638,16 +638,24 @@ rtx dest = operands[0]; rtx src = avr_eval_addr_attrib (operands[1]); - if (SUBREG_P(src) && (GET_CODE(XEXP(src,0)) == SYMBOL_REF) && - can_create_pseudo_p()) - { - rtx symbol_ref = XEXP(src, 0); - XEXP (src, 0) = copy_to_mode_reg (GET_MODE(symbol_ref), symbol_ref); - } - if (avr_mem_flash_p (dest)) DONE; + if (QImode == <MODE>mode + && SUBREG_P (src) + && CONSTANT_ADDRESS_P (SUBREG_REG (src))) + { + // store_bitfield may want to store a SYMBOL_REF or CONST in a + // structure that's represented as PSImode. As the upper 16 bits + // of PSImode cannot be expressed as an HImode subreg, the rhs is + // decomposed into QImode (word_mode) subregs of SYMBOL_REF, + // CONST or LABEL_REF; cf. PR71103. + + rtx const_addr = SUBREG_REG (src); + operands[1] = src = copy_rtx (src); + SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr); + } + /* One of the operands has to be in a register. */ if (!register_operand (dest, <MODE>mode) && !reg_or_0_operand (src, <MODE>mode)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 130d3e54b12..970dda1d72e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-06-20 Georg-Johann Lay <avr@gjlay.de> + + PR target/71103 + * gcc.target/avr/torture/pr71103-2.c: New test. + 2016-06-19 Martin Sebor <msebor@redhat.com> PR c/69507 diff --git a/gcc/testsuite/gcc.target/avr/torture/pr71103-2.c b/gcc/testsuite/gcc.target/avr/torture/pr71103-2.c new file mode 100644 index 00000000000..480ad05acab --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr71103-2.c @@ -0,0 +1,118 @@ +/* Use -g0 so that this test case doesn't just fail because + of PR52472. */ + +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -g0" } */ + +struct S12 +{ + char c; + const char *p; +}; + +struct S12f +{ + char c; + struct S12f (*f)(void); +}; + +struct S12labl +{ + char c; + void **labl; +}; + +struct S121 +{ + char c; + const char *p; + char d; +}; + +const char str[5] = "abcd"; + +struct S12 test_S12_0 (void) +{ + struct S12 s; + s.c = 'A'; + s.p = str; + return s; +} + +struct S12 test_S12_4 (void) +{ + struct S12 s; + s.c = 'A'; + s.p = str + 4; + return s; +} + +struct S12f test_S12f (void) +{ + struct S12f s; + s.c = 'A'; + s.f = test_S12f; + return s; +} + +struct S121 test_S121 (void) +{ + struct S121 s; + s.c = 'c'; + s.p = str + 4; + s.d = 'd'; + return s; +} + +extern void use_S12lab (struct S12labl*); + +struct S12labl test_S12lab (void) +{ + struct S12labl s; +labl:; + s.c = 'A'; + s.labl = &&labl; + return s; +} + +#ifdef __MEMX + +struct S13 +{ + char c; + const __memx char *p; +}; + +const __memx char str_x[] = "abcd"; + +struct S13 test_S13_0 (void) +{ + struct S13 s; + s.c = 'A'; + s.p = str_x; + return s; +} + +struct S13 test_S13_4a (void) +{ + struct S13 s; + s.c = 'A'; + s.p = str_x + 4; + return s; +} + +#ifdef __FLASH1 + +const __flash1 char str_1[] = "abcd"; + +struct S13 test_13_4b (void) +{ + struct S13 s; + s.c = 'A'; + s.p = str_1 + 4; + return s; +} + +#endif /* have __flash1 */ +#endif /* have __memx */ + |