aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-04-24 10:27:06 +0000
committerNick Clifton <nickc@gcc.gnu.org>2009-04-24 10:27:06 +0000
commit8d8256c19709b2ec4a2231f2e1b320966b503b3d (patch)
tree7d49c640adc0ea18bb60e199db6d5e7d3f1db3f0
parentc54ab0b5d10f8a81041e9403b3a3ae0d4587d499 (diff)
downloadgcc-8d8256c19709b2ec4a2231f2e1b320966b503b3d.zip
gcc-8d8256c19709b2ec4a2231f2e1b320966b503b3d.tar.gz
gcc-8d8256c19709b2ec4a2231f2e1b320966b503b3d.tar.bz2
frv.c (frv_frame_access): Do not use reg+reg addressing for DImode accesses.
* config/frv/frv.c (frv_frame_access): Do not use reg+reg addressing for DImode accesses. (frv_print_operand_address): Handle PLUS case. * config/frv/frv.h (FIXED_REGISTERS): Mark link register as fixed. From-SVN: r146694
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/frv/frv.c37
-rw-r--r--gcc/config/frv/frv.h2
3 files changed, 44 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a96520a..7ab7374 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2009-04-24 Nick Clifton <nickc@redhat.com>
+
+ * config/frv/frv.c (frv_frame_access): Do not use reg+reg
+ addressing for DImode accesses.
+ (frv_print_operand_address): Handle PLUS case.
+ * config/frv/frv.h (FIXED_REGISTERS): Mark link register as
+ fixed.
+
2009-04-24 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/39794
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index ecaf6d7..56c99ae 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -1687,7 +1687,21 @@ frv_frame_access (frv_frame_accessor_t *accessor, rtx reg, int stack_offset)
emit_insn (gen_rtx_SET (VOIDmode, reg, temp));
}
else
- emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
+ {
+ /* We cannot use reg+reg addressing for DImode access. */
+ if (mode == DImode
+ && GET_CODE (XEXP (mem, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG)
+ {
+ rtx temp = gen_rtx_REG (SImode, TEMP_REGNO);
+ rtx insn = emit_move_insn (temp,
+ gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0),
+ XEXP (XEXP (mem, 0), 1)));
+ mem = gen_rtx_MEM (DImode, temp);
+ }
+ emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
+ }
emit_use (reg);
}
else
@@ -1699,7 +1713,7 @@ frv_frame_access (frv_frame_accessor_t *accessor, rtx reg, int stack_offset)
frv_frame_insn (gen_rtx_SET (Pmode, mem, temp),
frv_dwarf_store (reg, stack_offset));
}
- else if (GET_MODE (reg) == DImode)
+ else if (mode == DImode)
{
/* For DImode saves, the dwarf2 version needs to be a SEQUENCE
with a separate save for each register. */
@@ -1707,6 +1721,19 @@ frv_frame_access (frv_frame_accessor_t *accessor, rtx reg, int stack_offset)
rtx reg2 = gen_rtx_REG (SImode, REGNO (reg) + 1);
rtx set1 = frv_dwarf_store (reg1, stack_offset);
rtx set2 = frv_dwarf_store (reg2, stack_offset + 4);
+
+ /* Also we cannot use reg+reg addressing. */
+ if (GET_CODE (XEXP (mem, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (mem, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (mem, 0), 1)) == REG)
+ {
+ rtx temp = gen_rtx_REG (SImode, TEMP_REGNO);
+ rtx insn = emit_move_insn (temp,
+ gen_rtx_PLUS (SImode, XEXP (XEXP (mem, 0), 0),
+ XEXP (XEXP (mem, 0), 1)));
+ mem = gen_rtx_MEM (DImode, temp);
+ }
+
frv_frame_insn (gen_rtx_SET (Pmode, mem, reg),
gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (2, set1, set2)));
@@ -2545,6 +2572,12 @@ frv_print_operand_address (FILE * stream, rtx x)
output_addr_const (stream, x);
return;
+ case PLUS:
+ /* Poorly constructed asm statements can trigger this alternative.
+ See gcc/testsuite/gcc.dg/asm-4.c for an example. */
+ frv_print_operand_memory_reference (stream, x, 0);
+ return;
+
default:
break;
}
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index f96bbc0..abe275f 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -799,7 +799,7 @@
1, 1, 1, 1, /* 164-167, accg8 - accg11 */ \
/* Other registers */ \
1, /* 168, AP - fake arg ptr */ \
- 0, /* 169, LR - Link register*/ \
+ 1, /* 169, LR - Link register*/ \
0, /* 170, LCR - Loop count reg*/ \
1, 1 /* 171-172, iacc0 */ \
}