This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: issues trying to add ColdFire v4e FPU support to gcc-20020107
- From: Peter Barada <pbarada at mail dot wm dot sps dot mot dot com>
- To: Peter dot Barada at motorola dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 16 Jan 2002 18:27:34 -0500
- Subject: Re: issues trying to add ColdFire v4e FPU support to gcc-20020107
- References: <200201162108.g0GL8Jc09870@hyper.wm.sps.mot.com>
>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)