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:
pgpzIMMVQYuj4.pgp
Description: PGP signature