This is the mail archive of the gcc@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]

Re: issues trying to add ColdFire v4e FPU support to gcc-20020107



>The .c.00.rtl dump for the insn 'fmove.d (%a0,%d0.l),%fp0' looks like:
>
>(insn 18 16 20 (set (reg:DF 35)
>        (mem:DF (plus:SI (reg:SI 33)
>                (reg:SI 34)) [0 S8 A16])) -1 (nil)
>    (nil))
>
>
>My problem is that the ColdFire FPU doesn't support the 'address
>register indirect with index' addressing mode.  I've mofidifued the
>movdf pattern to look like:

I found my problem.  It looks like in this case, LEGITIMIZE_ADDRESS
was presented with:

(plus:SI (mult:SI (reg:SI 30)
        (const_int 8 [0x8]))
    (mem/f:SI (reg/f:SI 24 virtual-incoming-args) [0 p+0 S4 A16]))

Which is converted into:

(plus:SI (reg:SI 32)
    (reg:SI 33))

At this point it was assumed that the address is valid.  I had to add
code to detect this case after the conversion, so LEGITIMIZE_ADDRESS
looks like:

#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)   \
{ register int ch = (X) != (OLDX);					\
  if (GET_CODE (X) == PLUS)						\
    { int copied = 0;							\
      if (GET_CODE (XEXP (X, 0)) == MULT)				\
	{ COPY_ONCE (X); XEXP (X, 0) = force_operand (XEXP (X, 0), 0);}	\
      if (GET_CODE (XEXP (X, 1)) == MULT)				\
	{ COPY_ONCE (X); XEXP (X, 1) = force_operand (XEXP (X, 1), 0);}	\
      if (ch && GET_CODE (XEXP (X, 1)) == REG				\
	  && GET_CODE (XEXP (X, 0)) == REG)				\
        { if (TARGET_CFV4E && GET_MODE_CLASS (MODE) == MODE_FLOAT)	\
          { COPY_ONCE (X); X = force_operand(X, 0); goto WIN;}		\
	else goto WIN; }						\
      if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); }		\
      if (GET_CODE (XEXP (X, 0)) == REG					\
	       || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND		\
		   && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG		\
		   && GET_MODE (XEXP (XEXP (X, 0), 0)) == HImode))	\
	{ register rtx temp = gen_reg_rtx (Pmode);			\
	  register rtx val = force_operand (XEXP (X, 1), 0);		\
	  emit_move_insn (temp, val);					\
	  COPY_ONCE (X);						\
	  XEXP (X, 1) = temp;						\
          if (TARGET_CFV4E && GET_MODE_CLASS (MODE) == MODE_FLOAT	\
              && GET_CODE (XEXP (X, 0)) == REG)				\
            X = force_operand(X, 0);					\
	  goto WIN; }							\
      else if (GET_CODE (XEXP (X, 1)) == REG				\
	       || (GET_CODE (XEXP (X, 1)) == SIGN_EXTEND		\
		   && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG		\
		   && GET_MODE (XEXP (XEXP (X, 1), 0)) == HImode))	\
	{ register rtx temp = gen_reg_rtx (Pmode);			\
	  register rtx val = force_operand (XEXP (X, 0), 0);		\
	  emit_move_insn (temp, val);					\
	  COPY_ONCE (X);						\
	  XEXP (X, 0) = temp;						\
          if (TARGET_CFV4E && GET_MODE_CLASS (MODE) == MODE_FLOAT	\
              && GET_CODE (XEXP (X, 1)) == REG)				\
            X = force_operand(X, 0);					\
	  goto WIN; }}}

Note the new code that after the emit_move_insn checks to see if the
result is now REG+REG.

All that *seems* to produce correct code, but I'm runnin into another
problem where FPU constants are being combined back together.  Given
the following code:

extern int foo1(void);
extern int foo2(void);
extern void bar(double,int);
void dbg_print_system_memory_usage (unsigned int print)
{
        unsigned int overhead;

        bar(foo1()/1048576.0, foo1());
        overhead = foo2();
        bar(overhead/1048576.0, overhead);
}


Reports:

/tmp/xx.c: In function `dbg_print_system_memory_usage':
/tmp/xx.c:12: unrecognizable insn:

(insn 78 69 57 (set (reg:DF 17 %fp1)
        (mem/u/f:DF (symbol_ref/u:SI ("*.LC0")) [3 S8 A32])) -1 (nil)
    (nil))
/tmp/xx.c:12: Internal compiler error in extract_insn, at recog.c:2129

The xx.c.21.rtl looks like:

(insn 74 26 28 (set (reg/f:SI 37)
        (symbol_ref/u:SI ("*.LC0"))) 35 {cfv4_movsi} (nil)
    (expr_list:REG_EQUIV (symbol_ref/u:SI ("*.LC0"))
        (nil)))

(insn 28 74 30 (set (reg:DF 35)
        (mult:DF (reg:DF 35)
            (mem/u/f:DF (reg/f:SI 37) [3 S8 A32]))) 171 {muldf3_v4e} (insn_list 25 (insn_list 23 (nil)))
    (expr_list:REG_DEAD (reg/f:SI 37)
        (nil)))

And this is combined back together.  I guess I'll have to add into
LEGITIMIZE_ADDRESS code to force the operand into a register if the
mode is float and the RTL is SYMBOL_REF.

Any ideas?

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]