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: 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)


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