This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: ColdFire v4e FPU addressing problems
- From: Peter Barada <pbarada at mail dot wm dot sps dot mot dot com>
- To: gcc at gcc dot gnu dot org
- Date: Fri, 18 Jan 2002 10:29:56 -0500
- Subject: Re: ColdFire v4e FPU addressing problems
I'm slogging along adding in FPU support for ColdFire's FPU, and I've
run into a problem that I'm not sure of how to fix.
The V4E FPU can not load values using an absolute address, so i
modified movdf to push contants into memory, and force symbol
addresses into registers:
(define_expand "movdf"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand:DF 1 "general_operand" ""))]
""
"
{
if (TARGET_CFV4E) {
/* The ColdFire FPU can't deal with absolute addresses or double
* constants, so push it to memory */
if (CONSTANT_P (operands[1])) {
operands[1] = force_const_mem(DFmode, operands[1]);
if (! memory_address_p (DFmode, XEXP (operands[1], 0))
&& ! reload_in_progress)
operands[1] = change_address (operands[1], DFmode,
XEXP (operands[1], 0));
}
if (symbolic_operand(operands[0], SImode))
operands[0] = force_reg(SImode, XEXP (operands[0], 0));
if (symbolic_operand(operands[1], SImode))
operands[1] = force_reg(SImode, XEXP (operands[1], 0));
}
}")
(define_insn "movdf_v4e"
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,<Q>U,r,f")
(match_operand:DF 1 "valid_fpu_operand" "f<Q>U,f,f,r"))]
"TARGET_CFV4E"
"*
{
if (which_alternative == 2)
return \"subq%.l %#8,%%sp\;fmove%.d %1,%@\;move%.l %+,%0\;move%.l %+,%R0\";
if (which_alternative == 3)
return \"move%.l %R1,%-\;move%.l %1,%-\;f%&move%.d %@,%0\;addq%.l #8,%%sp\";
return \"fmove%.d %1,%0\";
}")
Note the 'valid_fpu_operand' predicate which I had to invent to
reject constants since the gcse pass tried to propagate them.
The constraint of '<Q>U' alloew predecrement, register indirect,
postincrement, an register indirect with offset. Note that 'm' and
'o' are rejected as constraints since the FPU can't deal with (R+R)
addressing either.
The current problem is that in global_alloc(), the reload pass is trying
to reload FPU constants, and at line 7518 of gcc/reload1.c, the following
code executes:
/* If IN is a simple operand, use gen_move_insn. */
else if (GET_RTX_CLASS (GET_CODE (in)) == 'o' || GET_CODE (in) == SUBREG)
emit_insn (gen_move_insn (out, in));
(gdb) call debug_rtx(out)
(reg:DF 17 %fp1)
(gdb) call debug_rtx(in)
(const_double:DF 0 [0x0] 0 [0x0] 1073643520 [0x3ffe8000])
(gdb) down
#1 0x081033ff in emit_insn (pattern=0x401abfb0)
at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3/gcc/emit-rtl.c:3934
(gdb) call debug_rtx(pattern)
(set (reg:DF 17 %fp1)
(mem/u/f:DF (symbol_ref/u:SI ("*.LC1")) [6 S8 A32]))
(gdb)
Since the FPU can't deal with absolute addresses, this fails with:
/tmp/boldfill.c:44: unrecognizable insn:
(insn 246 101 103 (set (reg:DF 17 %fp1)
(mem/u/f:DF (symbol_ref/u:SI ("*.LC1")) [6 S8 A32])) -1 (nil)
(nil))
/tmp/boldfill.c:44: Internal compiler error in extract_insn, at recog.c:2129
Does anyone have any ideas how I can convince reload that if it wants
to reload the FPU constant that it has to use an address register to
hold its address and load it indirectly...
Thanks for any advice,
--
Peter Barada Peter.Barada@motorola.com
Wizard 781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola) 781-270-0193 (fax)