2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-09 20:31:36 +08:00

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
This commit is contained in:
Nick Clifton 2009-04-24 10:27:06 +00:00 committed by Nick Clifton
parent c54ab0b5d1
commit 8d8256c197
3 changed files with 44 additions and 3 deletions
gcc

@ -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

@ -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;
}

@ -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 */ \
}