public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re^2: Restricted addressing modes in ColdFire FPU for DFmode
@ 2001-12-07 17:35 Peter Barada
  2001-12-08 22:46 ` Richard Henderson
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Barada @ 2001-12-07 17:35 UTC (permalink / raw)
  To: gcc; +Cc: Peter.Barada


>>I'm working on adding the V4E ColdFire FPU instructions to gcc-2.95.3,
>>and I've been having a very hard time convincing gcc to deal with the
>>restricted addressing modes that the ColdFire FPU supports.

With the previous changes that I've made to add a cannot_combine flag
to tell the cominber that it shouldn't combine the following:

(insn 8 6 9 (set (reg:SI 31)
        (symbol_ref:SI ("zat"))) -1 (nil)
    (expr_list:REG_EQUAL (symbol_ref:SI ("zat"))
        (nil)))

(insn/C 9 8 11 (set (reg:DF 30)
        (mem:DF (reg:SI 31) 0)) -1 (nil)
    (nil))


Everything works(at least for adddf3, subdf3, muldf3, divdf3, negdf2,
etc)  Note the "/C" on the memory reference which indicates that the
'cannot_combine' bit in the RTX is set whihc tells
cant_combine_insn_p() to return 1 early.  

Now I'm trying to deal with the other side which is storing the value
back to memory.  Here's the result of yy.c.lreg for a store:

(insn 10 16 11 (set (reg:SI 30)
        (symbol_ref:SI ("zat"))) 47 {cfv4_movsi} (nil)
    (expr_list:REG_EQUIV (symbol_ref:SI ("zat"))
        (nil)))

(insn/C 11 10 0 (set (mem/f:DF (symbol_ref:SI ("zat")) 0)
        (mem:DF (reg:SI 30) 0)) 67 {movdf_v4e} (insn_list 10 (nil))
    (expr_list:REG_DEAD (reg:SI 30)
        (nil)))


Since its survived the combiner, I'd expect everything to be happy and
to match up with my machine description quite well, but somewhere
between here and where it dumps yy.c.greg, it dies with(and the
traceback of): 

/tmp/yy.c: In function `a':
/tmp/yy.c:5: internal error--insn does not satisfy its constraints:

(insn 20 11 17 (set (mem/f:DF (symbol_ref:SI ("zat")) 0)
        (reg:DF 16 %fp0)) 67 {movdf_v4e} (nil)
    (nil))

(gdb) where
#0  exit (status=33) at exit.c:40
#1  0x0804944e in fatal_insn ()
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-2.95.3/gcc/toplev.c:1480
#2  0x0804947e in fatal_insn_not_found ()
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-2.95.3/gcc/toplev.c:1494
#3  0x08133ecc in reload_cse_simplify_operands (insn=0x81df5c8)
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-2.95.3/gcc/reload1.c:9245
#4  0x08133873 in reload_cse_regs_1 (first=0x81e0fec)
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-2.95.3/gcc/reload1.c:8903
#5  0x08133ad0 in reload_cse_regs (first=0x81e0fec)
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-2.95.3/gcc/reload1.c:9014
#6  0x0804c78f in rest_of_compilation (decl=0x81eeea4)
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-2.95.3/gcc/toplev.c:4204
#7  0x0816fcb5 in finish_function (nested=0)
    at /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-2.95.3/gcc/c-decl.c:7270


With the RTL looking like:

(define_expand "movdf"
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
	(match_operand:DF 1 "nonimmediate_operand" ""))]
  ""
  "
{
  rtx insn;
  int cannot_combine = FALSE;

  if (TARGET_FPU_V4E) {
    /* 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));
    }
    /* Since the Coldfire can't deal with absolute addresses, force
     * the address of the reference into a register and do it indirect */
    if (!reload_in_progress) {
      if (GET_CODE (operands[0]) == MEM
          && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) {
        operands[1] = gen_rtx (MEM, DFmode,
                             force_reg (Pmode, XEXP (operands[0], 0)));
        cannot_combine = TRUE;
      }
      if (GET_CODE (operands[1]) == MEM
          && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) {
        operands[1] = gen_rtx (MEM, DFmode,
                             force_reg (Pmode, XEXP (operands[1], 0)));
        cannot_combine = TRUE;
      }
      if (cannot_combine) {
        /* Set RTX_CANNOT_COMBINE to prevent the combiner from putting
         this back together, but only on the insn, not the operand! */
        insn = emit_insn(gen_rtx_SET(VOIDmode, operands[0], operands[1]));
        RTX_CANNOT_COMBINE_P(insn) = 1;
        DONE;
      }
    }
  }
}")

(define_insn "movdf_v4e"
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,<Q>S")
	(match_operand:DF 1 "nonimmediate_operand" "f<Q>S,f"))]
  "TARGET_FPU_V4E"
  "*
{
  return \"fmove%.d %1,%0\";
}")


Note that 'Q' is register indirect, and 'S' is register indirect with
offset, both of which are allowed by the Coldfire FPU.  I thought the
combining pass was the only one to paste instructions together.  What
am I missing and how best can I convince gcc to use register indirect
to store the DP register to memory?

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)

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-12-10 22:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-07 17:35 Re^2: Restricted addressing modes in ColdFire FPU for DFmode Peter Barada
2001-12-08 22:46 ` Richard Henderson
2001-12-10  8:15   ` Peter Barada
2001-12-10 13:11     ` Richard Henderson
2001-12-10 13:59       ` Peter Barada
2001-12-10 15:06         ` Peter Barada

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).