aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2020-01-24 08:57:46 -0700
committerJeff Law <law@redhat.com>2020-01-24 08:57:46 -0700
commit64c9f2d9972ad359a32f0a97ee0a806c2532db15 (patch)
tree16486e0032eede7daec136bd56085884b531be21
parente6e5cd2fd70b73eaa6bead8bbaa25b0e40b4ca55 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/h8300/h8300.c24
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/h8300/pr13721.c71
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;
+}