diff options
author | Jeff Law <law@redhat.com> | 2020-01-24 08:57:46 -0700 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 2020-01-24 08:57:46 -0700 |
commit | 64c9f2d9972ad359a32f0a97ee0a806c2532db15 (patch) | |
tree | 16486e0032eede7daec136bd56085884b531be21 | |
parent | e6e5cd2fd70b73eaa6bead8bbaa25b0e40b4ca55 (diff) | |
download | gcc-64c9f2d9972ad359a32f0a97ee0a806c2532db15.zip gcc-64c9f2d9972ad359a32f0a97ee0a806c2532db15.tar.gz gcc-64c9f2d9972ad359a32f0a97ee0a806c2532db15.tar.bz2 |
Emit reasonable diagnostic rather than ICE on invalid ASM on H8 port
PR target/13721
* config/h8300/h8300.c (h8300_print_operand): Only call byte_reg
for REGs. Call output_operand_lossage to get more reasonable
diagnostics.
PR target/13721
* gcc.target/h8300/pr13721.c: New test.
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/h8300/pr13721.c | 71 |
4 files changed, 101 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 27e5ec2..4d851c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-01-24 Jeff Law <law@redhat.com> + + PR target/13721 + * config/h8300/h8300.c (h8300_print_operand): Only call byte_reg + for REGs. Call output_operand_lossage to get more reasonable + diagnostics. + 2020-01-24 Andrew Stubbs <ams@codesourcery.com> * config/gcn/gcn-valu.md (vec_cmp<mode>di): Use diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index ffbfa9e..def8be3 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -1647,40 +1647,52 @@ h8300_print_operand (FILE *file, rtx x, int code) case 's': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%ld", (INTVAL (x)) & 0xff); - else + else if (GET_CODE (x) == REG) fprintf (file, "%s", byte_reg (x, 0)); + else + output_operand_lossage ("Expected register or constant integer."); break; case 't': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff); - else + else if (GET_CODE (x) == REG) fprintf (file, "%s", byte_reg (x, 1)); + else + output_operand_lossage ("Expected register or constant integer."); break; case 'w': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%ld", INTVAL (x) & 0xff); - else + else if (GET_CODE (x) == REG) fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 2 : 0)); + else + output_operand_lossage ("Expected register or constant integer."); break; case 'x': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff); - else + else if (GET_CODE (x) == REG) fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 3 : 1)); + else + output_operand_lossage ("Expected register or constant integer."); break; case 'y': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%ld", (INTVAL (x) >> 16) & 0xff); - else + else if (GET_CODE (x) == REG) fprintf (file, "%s", byte_reg (x, 0)); + else + output_operand_lossage ("Expected register or constant integer."); break; case 'z': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%ld", (INTVAL (x) >> 24) & 0xff); - else + else if (GET_CODE (x) == REG) fprintf (file, "%s", byte_reg (x, 1)); + else + output_operand_lossage ("Expected register or constant integer."); break; default: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c465ff9..c069990 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-01-24 Jeff Law <law@redhat.com + + PR target/13721 + * gcc.target/h8300/pr13721.c: New test. + 2020-01-24 Christophe Lyon <christophe.lyon@linaro.org> PR debug/92763 diff --git a/gcc/testsuite/gcc.target/h8300/pr13721.c b/gcc/testsuite/gcc.target/h8300/pr13721.c new file mode 100644 index 0000000..817b537 --- /dev/null +++ b/gcc/testsuite/gcc.target/h8300/pr13721.c @@ -0,0 +1,71 @@ +static __inline__ __attribute__((always_inline)) void set_bit(int nr, volatile void * addr) +{ + volatile unsigned char *b_addr; + b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); + nr &= 7; + if (__builtin_constant_p (nr)) + { + switch(nr) + { + case 0: + __asm__("bset #0,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + case 1: + __asm__("bset #1,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + case 2: + __asm__("bset #2,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + case 3: + __asm__("bset #3,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + case 4: + __asm__("bset #4,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + case 5: + __asm__("bset #5,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + case 6: + __asm__("bset #6,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + case 7: + __asm__("bset #7,%0" :"+m"(*b_addr) :"m"(*b_addr)); + break; + } + } + else + { + __asm__("bset %w1,%0" :"+m"(*b_addr) :"g"(nr),"m"(*b_addr)); /* { dg-error "invalid 'asm'" "" } */ + + } +} + +static __inline__ __attribute__((always_inline)) int test_bit(int nr, const volatile void * addr) +{ + return (*((volatile unsigned char *)addr + ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0; +} + +struct a { + unsigned long a; +}; + +void dummy(struct a *a, int b); + +int ice_func(struct a *a, int b) +{ + int c,d; + unsigned int e; + + for(c=0;c<b;c++) { + for(d=b; d <= b; d++) { + if (!test_bit(d, &e)) { + dummy(a, d * a->a); + dummy(a, d * a->a); + set_bit(d, &e); + } + } + dummy(a, d * a->a); + } + + return 0; +} |