This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Hello!
I think I found a bug in the fr30 port of the gcc-backend of GCC4.1.1, but I
am not sure, how to fix it. The situation is as follows:
In case of a "movdi" pattern with memory_operand as operand[0] and
register_operand as operand[1] gcc produces wrong code. A define_split is in
fr30.md (lines 381-408) which calls fr30_move_double () in fr30.c as
preparation statement. This function handles different cases, the relevant
lines are 887-923:
{
rtx addr = XEXP (dest, 0);
rtx src0;
rtx src1;
gcc_assert (GET_CODE (addr) == REG);
src0 = operand_subword (src, 0, TRUE, mode);
src1 = operand_subword (src, 1, TRUE, mode);
emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),
src0));
if (REGNO (addr) == STACK_POINTER_REGNUM
|| REGNO (addr) == FRAME_POINTER_REGNUM)
emit_insn (gen_rtx_SET (VOIDmode,
adjust_address (dest, SImode, UNITS_PER_WORD),
src1));
else
{
rtx new_mem;
/* We need a scratch register to hold the value of 'address + 4'.
We ought to allow gcc to find one for us, but for now, just
push one of the source registers. */
emit_insn (gen_movsi_push (src0));
emit_insn (gen_movsi_internal (src0, addr));
emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
new_mem = gen_rtx_MEM (SImode, src0);
MEM_COPY_ATTRIBUTES (new_mem, dest);
emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
emit_insn (gen_movsi_pop (src0));
}
}
As you can see, the 64bit source operand is splitted in 2 32bit operands (fr30
is a 32bit machine) and one part is moved, then src0 is pushed to stack and
then clobbered for address calculation for the second move. Then the original
value of src0 is pop-ed back from stack. This code may be not nice, but it
should work.
The insn are emmited right but the problem is, that the following optimization
passes notice, that the value we pop-ed from stack to src0 is not used
afterwards (in most cases) and the instruction is simply removed. But this is
bad, because we have a wrong stack-pointer in that case. It was pushed but
never poped.
Has anybody an idea how to fix this behavior ?
I could imagine two ways:
1. Find other ways to move the values, maybe without using the stack.
2. Change the movsi_push and movsi_pop patterns to make gcc aware that they
change r15. (r15 is the stack pointer register)
Does anybody have some hints for me ?
Thanks,
Lars
Attachment:
pgp00000.pgp
Description: PGP signature
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |