diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 18 | ||||
-rw-r--r-- | gcc/recog.c | 44 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr48774.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/pr52125.c | 20 |
7 files changed, 96 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1140054..b2540ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 6c6fe61..5bad0f8 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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; diff --git a/gcc/recog.c b/gcc/recog.c index b81214c..e2caf9859 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -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. */ @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4cc8d9f..4c085c6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/pr48774.c b/gcc/testsuite/gcc.dg/pr48774.c index abd8c23..91ce361 100644 --- a/gcc/testsuite/gcc.dg/pr48774.c +++ b/gcc/testsuite/gcc.dg/pr48774.c @@ -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 index 0000000..cfa8d68 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/pr52125.c @@ -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\\)" } } */ |