bug in fr30 port

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux