]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/52125 (Problems with LO16 asm operands on MIPS)
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 23 Jan 2014 08:24:38 +0000 (08:24 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 23 Jan 2014 08:24:38 +0000 (08:24 +0000)
gcc/
PR target/52125
* rtl.h (get_referenced_operands): Declare.
* recog.c (get_referenced_operands): New function.
* config/mips/mips.c (mips_reorg_process_insns): Check which asm
operands have been referenced when recording LO_SUM references.

gcc/testsuite/
PR target/52125
* gcc.dg/pr48774.c: Remove skip for mips_rel.
* gcc.target/mips/pr52125.c: New test.

From-SVN: r206955

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/recog.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr48774.c
gcc/testsuite/gcc.target/mips/pr52125.c [new file with mode: 0644]

index 1140054ce281585dc79f0c4451125bf9cf2fabac..b2540ec79f6fe56a8be83b8f26604e388a865376 100644 (file)
@@ -1,3 +1,11 @@
+2014-01-23  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR target/52125
+       * rtl.h (get_referenced_operands): Declare.
+       * recog.c (get_referenced_operands): New function.
+       * config/mips/mips.c (mips_reorg_process_insns): Check which asm
+       operands have been referenced when recording LO_SUM references.
+
 2014-01-22  David Holsgrove <david.holsgrove@xilinx.com>
 
        * config/microblaze/microblaze.md: Correct bswaphi2 insn.
index 6c6fe61be398e115ccc6c6d010eb31dc519aa439..5bad0f8b12272765b955b379c25be5b2f26dffd8 100644 (file)
@@ -16097,7 +16097,23 @@ mips_reorg_process_insns (void)
   for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
     FOR_EACH_SUBINSN (subinsn, insn)
       if (USEFUL_INSN_P (subinsn))
-       for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);
+       {
+         rtx body = PATTERN (insn);
+         int noperands = asm_noperands (body);
+         if (noperands >= 0)
+           {
+             rtx *ops = XALLOCAVEC (rtx, noperands);
+             bool *used = XALLOCAVEC (bool, noperands);
+             const char *string = decode_asm_operands (body, ops, NULL, NULL,
+                                                       NULL, NULL);
+             get_referenced_operands (string, used, noperands);
+             for (int i = 0; i < noperands; ++i)
+               if (used[i])
+                 for_each_rtx (&ops[i], mips_record_lo_sum, &htab);
+           }
+         else
+           for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);
+       }
 
   last_insn = 0;
   hilo_delay = 2;
index b81214cf41c57c9ea531b17fa9f13e1a21bb54b5..e2caf9859d8301309676a73656819a787c1e8b77 100644 (file)
@@ -1620,6 +1620,50 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
   return ASM_OPERANDS_TEMPLATE (asmop);
 }
 
+/* Parse inline assembly string STRING and determine which operands are
+   referenced by % markers.  For the first NOPERANDS operands, set USED[I]
+   to true if operand I is referenced.
+
+   This is intended to distinguish barrier-like asms such as:
+
+      asm ("" : "=m" (...));
+
+   from real references such as:
+
+      asm ("sw\t$0, %0" : "=m" (...));  */
+
+void
+get_referenced_operands (const char *string, bool *used,
+                        unsigned int noperands)
+{
+  memset (used, 0, sizeof (bool) * noperands);
+  const char *p = string;
+  while (*p)
+    switch (*p)
+      {
+      case '%':
+       p += 1;
+       /* A letter followed by a digit indicates an operand number.  */
+       if (ISALPHA (p[0]) && ISDIGIT (p[1]))
+         p += 1;
+       if (ISDIGIT (*p))
+         {
+           char *endptr;
+           unsigned long opnum = strtoul (p, &endptr, 10);
+           if (endptr != p && opnum < noperands)
+             used[opnum] = true;
+           p = endptr;
+         }
+       else
+         p += 1;
+       break;
+
+      default:
+       p++;
+       break;
+      }
+}
+
 /* Check if an asm_operand matches its constraints.
    Return > 0 if ok, = 0 if bad, < 0 if inconclusive.  */
 
index 10ee818a84d7fc4da64f38f7f7d7f8d384495b90..f1cda4c04b59a94829c6841341ecdd7b4242aae6 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2169,6 +2169,7 @@ extern rtx extract_asm_operands (rtx);
 extern int asm_noperands (const_rtx);
 extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
                                        enum machine_mode *, location_t *);
+extern void get_referenced_operands (const char *, bool *, unsigned int);
 
 extern enum reg_class reg_preferred_class (int);
 extern enum reg_class reg_alternate_class (int);
index 4cc8d9f8984234ee4be69715a077ba016506bf09..4c085c63da18241db689214cb0feafeb33bbdff8 100644 (file)
@@ -1,3 +1,9 @@
+2014-01-23  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR target/52125
+       * gcc.dg/pr48774.c: Remove skip for mips_rel.
+       * gcc.target/mips/pr52125.c: New test.
+
 2014-01-22  Marek Polacek  <polacek@redhat.com>
 
        PR c/59891
index abd8c2319326451270cab90971b55451544bc8d5..91ce361ccb38645ce4a249d80bc526b382d96ae6 100644 (file)
@@ -1,6 +1,5 @@
 /* PR target/48774 */
 /* { dg-do run } */
-/* { dg-skip-if "PR 52125" { mips_rel } { "*" } { "" } } */
 /* { dg-options "-O2 -funroll-loops" } */
 
 extern void abort (void);
diff --git a/gcc/testsuite/gcc.target/mips/pr52125.c b/gcc/testsuite/gcc.target/mips/pr52125.c
new file mode 100644 (file)
index 0000000..cfa8d68
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-options "addressing=absolute" } */
+
+int a, b, c, d;
+
+NOMIPS16 void
+foo (void)
+{
+  asm ("%1 %z3"
+       : "=m" (a), "=m" (b)
+       : "m" (c), "m" (d));
+}
+
+/* { dg-final { scan-assembler-not "%hi\\(a\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(a\\)" } } */
+/* { dg-final { scan-assembler "%hi\\(b\\)" } } */
+/* { dg-final { scan-assembler "%lo\\(b\\)" } } */
+/* { dg-final { scan-assembler-not "%hi\\(c\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(c\\)" } } */
+/* { dg-final { scan-assembler "%hi\\(d\\)" } } */
+/* { dg-final { scan-assembler "%lo\\(d\\)" } } */