Emit reasonable diagnostic rather than ICE on invalid ASM on H8 port
authorJeff Law <law@redhat.com>
Fri, 24 Jan 2020 15:57:46 +0000 (08:57 -0700)
committerJeff Law <law@redhat.com>
Fri, 24 Jan 2020 15:57:46 +0000 (08:57 -0700)
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.

gcc/ChangeLog
gcc/config/h8300/h8300.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/h8300/pr13721.c [new file with mode: 0644]

index 27e5ec234099681a585d26545207805aa5de252c..4d851c0b170fa3c72b91bcf126e2569f74ba7f94 100644 (file)
@@ -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
index ffbfa9eaaa92442d7933a8f3a5ed4cc0022e8924..def8be344af2b95e823d27665c0a3aebc1f81ac4 100644 (file)
@@ -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:
index c465ff99541b24fd223b47349f8f3e7422dd58b2..c0699907f1c7fe67a5373d7b5d17881093b6f6c9 100644 (file)
@@ -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 (file)
index 0000000..817b537
--- /dev/null
@@ -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;
+}