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; 9+ 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] 9+ messages in thread

* Re: Re^2: Restricted addressing modes in ColdFire FPU for DFmode
  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
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2001-12-08 22:46 UTC (permalink / raw)
  To: Peter Barada; +Cc: gcc, Peter.Barada

On Fri, Dec 07, 2001 at 08:07:31PM -0500, Peter Barada wrote:
> 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))

This is incorrect.  If you'd defined a legitimate address
properly, you wouldn't be having this problem.


r~

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

* Re: Restricted addressing modes in ColdFire FPU for DFmode
  2001-12-08 22:46 ` Richard Henderson
@ 2001-12-10  8:15   ` Peter Barada
  2001-12-10 13:11     ` Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Barada @ 2001-12-10  8:15 UTC (permalink / raw)
  To: rth; +Cc: Peter.Barada, gcc, Peter.Barada


>> 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))
>
>This is incorrect.  If you'd defined a legitimate address
>properly, you wouldn't be having this problem.

Is that GO_IF_LEGITMATE_ADDRESS()?

-- 
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] 9+ messages in thread

* Re: Restricted addressing modes in ColdFire FPU for DFmode
  2001-12-10  8:15   ` Peter Barada
@ 2001-12-10 13:11     ` Richard Henderson
  2001-12-10 13:59       ` Peter Barada
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2001-12-10 13:11 UTC (permalink / raw)
  To: Peter Barada; +Cc: Peter.Barada, gcc

On Mon, Dec 10, 2001 at 11:07:25AM -0500, Peter Barada wrote:
> Is that GO_IF_LEGITMATE_ADDRESS()?

Yes.


r~

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

* Re: Restricted addressing modes in ColdFire FPU for DFmode
  2001-12-10 13:11     ` Richard Henderson
@ 2001-12-10 13:59       ` Peter Barada
  2001-12-10 15:06         ` Peter Barada
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Barada @ 2001-12-10 13:59 UTC (permalink / raw)
  To: rth; +Cc: Peter.Barada, gcc


>> Is that GO_IF_LEGITMATE_ADDRESS()?
>
>Yes.

Thanks.  From that suggestion I abandoned my previous path, and
started hacking up a version for coldfire, and I have almost
everything working(or at least load/store, add/sub/mul/div) except for
addresses such as:  

   (mem/s:DF (plus:SI (reg:SI 36) (reg:SI 40)) 0)

I modified GO_IF_LEGITIMATE_ADDRESS to be:

#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\
{ if (check_v4e_fpu_address(MODE, X)) { \
    GO_IF_NONINDEXED_ADDRESS (X, ADDR);					\
    GO_IF_INDEXED_ADDRESS (X, ADDR);					\
    if (flag_pic && MODE == CASE_VECTOR_MODE && GET_CODE (X) == PLUS	\
        && LEGITIMATE_INDEX_P (XEXP (X, 0))				\
        && GET_CODE (XEXP (X, 1)) == LABEL_REF)				\
      goto ADDR; \
  } \
}

int check_v4e_legitimate_address(MODE, X)
     enum machine_mode MODE;
     rtx X;
{
  /* If v4e and float, only accept addressing modes 2, 3, 4, and 5 */
  if (TARGET_FPU_V4E && GET_MODE_CLASS (MODE) == MODE_FLOAT) {
    /* mode 2 */
    if (LEGITIMATE_BASE_REG_P(X))
      return TRUE;
    /* mode 3&4 */
    if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)
        && LEGITIMATE_BASE_REG_P (XEXP (X, 0)))
      return TRUE;
    /* mode 5 */
    if (GET_CODE (X) == PLUS
        && LEGITIMATE_BASE_REG_P (XEXP (X, 0))
        && GET_CODE (XEXP (X, 1)) == CONST_INT
        && (((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000))
      return TRUE;
    
    return FALSE;
  }
  return TRUE;
}


I'd have thourhg that check_v4e_legitimate_address() would have
rejected double indexed addressing (addressing mode 6), but I
confident I can figure out what's gone wrong...

Again, thanks for the suggestion.

-- 
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] 9+ messages in thread

* Re: Restricted addressing modes in ColdFire FPU for DFmode
  2001-12-10 13:59       ` Peter Barada
@ 2001-12-10 15:06         ` Peter Barada
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Barada @ 2001-12-10 15:06 UTC (permalink / raw)
  To: rth; +Cc: Peter.Barada, gcc


>
>I'd have thought that check_v4e_legitimate_address() would have
>rejected double indexed addressing (addressing mode 6), but I'm
>confident I can figure out what's gone wrong...

I modified LEGITIMIZE_ADDRESS to be the following(change marked with
'v4e') to force reg+reg into a register, and everything seems to
work(modulo *extremely* limited testing). 

#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
#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);}	\
/* v4e */  if (TARGET_FPU_V4E && GET_MODE_CLASS (MODE) == MODE_FLOAT)   \
/* v4e */  { X = force_reg(Pmode, X); goto WIN; }                       \
      if (ch && GET_CODE (XEXP (X, 1)) == REG				\
	  && GET_CODE (XEXP (X, 0)) == REG)				\
	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;						\
	  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;						\
	  goto WIN; }}}

Once I write the rest of the code, I'll come back and see if I can
improve on the current solution.

Again, thanx to everyone for all your help!

-- 
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] 9+ messages in thread

* Re: Restricted addressing modes in ColdFire FPU for DFmode
  2001-12-07 11:27 ` Alan Lehotsky
@ 2001-12-07 13:01   ` Peter Barada
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Barada @ 2001-12-07 13:01 UTC (permalink / raw)
  To: apl; +Cc: Peter.Barada, gcc, 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.
>>
>>.....
>>(define_insn "movdf_v4e"
>>  [(set (match_operand:DF 0 "general_operand" "=f,<Q>S")
>>	(match_operand:DF 1 "general_operand" "f<Q>S,f"))]
>>  "TARGET_FPU_V4E"
>>  "*
>>{
>>  return \"fmove%.d %1,%0\";
>>}")
>>
>
>	What happens if you change the predicate in the define_insn to
>
>		"nonimmedate_operand"
>
>	for BOTH operands[0] and operands[1]?

If I use the following RTL:

(define_expand "movdf"
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
	(match_operand:DF 1 "nonimmediate_operand" ""))]
  ""
  "")

(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\";
}")


I get:

/tmp/z.c: In function `x':
/tmp/z.c:4: internal error--unrecognizable insn:

(insn 8 16 9 (set (reg/i:DF 16 %fp0)
        (const_double:DF (const_int 0 [0x0]) 0 [0x0] 0 [0x0] 1073643520 [0x3ffe8000])) -1 (nil)
    (expr_list:REG_EQUAL (const_double:DF (const_int 0 [0x0]) 0 [0x0] 0 [0x0] 1073643520 [0x3ffe8000])
        (nil)))

So I have to push the constant to memory. If I use the rtl:


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

  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 && 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)));
#if 0
      /* 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;
#endif
    }
  }
}")

(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\";
}")

I get:

/tmp/z.c: In function `x':
/tmp/z.c:4: internal error--insn does not satisfy its constraints:

(insn 21 8 9 (set (reg:DF 17 %fp1)
        (mem:DF (symbol_ref/u:SI ("*.LC0")) 0)) 67 {movdf_v4e} (nil)
    (nil))


If I turn the '#if 0' to '#if 1' then it works(as long as all the
other code to support RTX_CANNOT_COMBINE_P is there as well)...


-- 
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] 9+ messages in thread

* Re: Restricted addressing modes in ColdFire FPU for DFmode
  2001-12-07 10:13 Peter Barada
@ 2001-12-07 11:27 ` Alan Lehotsky
  2001-12-07 13:01   ` Peter Barada
  0 siblings, 1 reply; 9+ messages in thread
From: Alan Lehotsky @ 2001-12-07 11:27 UTC (permalink / raw)
  To: Peter Barada; +Cc: gcc, Peter.Barada

At 1:02 PM -0500 12/7/01, Peter Barada wrote:

>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.
>
>.....
>(define_insn "movdf_v4e"
>  [(set (match_operand:DF 0 "general_operand" "=f,<Q>S")
>	(match_operand:DF 1 "general_operand" "f<Q>S,f"))]
>  "TARGET_FPU_V4E"
>  "*
>{
>  return \"fmove%.d %1,%0\";
>}")
>

	What happens if you change the predicate in the define_insn to

		"nonimmedate_operand"

	for BOTH operands[0] and operands[1]?

	That would cause the combined instruction to fail being recognized...

-- 
------------------------------------------------------------------------

		    Quality Software Management
		http://home.earthlink.net/~qsmgmt
			apl@alum.mit.edu
			(978)287-0435 Voice
			(978)808-6836 Cell
			(978)287-0436 Fax

	Software Process Improvement and Management Consulting
	     Language Design and Compiler Implementation

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

* Re: Restricted addressing modes in ColdFire FPU for DFmode
@ 2001-12-07 10:13 Peter Barada
  2001-12-07 11:27 ` Alan Lehotsky
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Barada @ 2001-12-07 10:13 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.

The fmove.d instruction supports only the following addressing modes:
predecrement, postincement, indirect, inderect with offset, and
pc-relative with offset(for loads).  Note that neither register direct
nor absolute addressing is supported.  I created to following RTL for
movdf:

(define_expand "movdf"
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
	(match_operand:DF 1 "general_operand" ""))]
  ""
  "
{
  if (TARGET_FPU_V4E) {
    /* The ColdFire FPU can't deal with absolute addresses or double
     * constants, so push the constant 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 && 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)));
  }
}")

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


And that split up symbolic addressing quite well(as well as handled constants):

(insn 8 6 9 (set (reg:SI 30)
        (symbol_ref/u:SI ("*.LC0"))) -1 (nil)
    (expr_list:REG_EQUAL (symbol_ref/u:SI ("*.LC0"))
        (nil)))

(insn 9 8 10 (set (reg/i:DF 16 %fp0)
        (mem:DF (reg:SI 30) 0)) -1 (nil)
    (nil))

but the combiner converted that back into:

(insn 9 8 10 (set (reg/i:DF 16 %fp0)
        (mem:DF (symbol_ref/u:SI ("*.LC0")) 0)) 67 {movdf_v4e} (nil)
    (expr_list:REG_EQUAL (const_double:DF (mem/u:DF (symbol_ref/u:SI ("*.LC0")) 0) 0 [0x0] 0 [0x0] 1073643520 [0x3ffe8000])
        (nil)))

Which died with:

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

(insn 21 8 9 (set (reg:DF 17 %fp1)
        (mem:DF (symbol_ref/u:SI ("*.LC0")) 0)) 67 {movdf_v4e} (nil)
    (nil))



I looked over combine.c, and I didn't see anyway that a target can
prevent combination from happening.  So in desperation I decided to
add a flag to the rtx struct:

  /* 1 in an INSN or a SET if this rtx can *not* be combined with
     either RTX next to it.  Its necessary to limit the combiner from
     creating RTX that the machine description worked very hard to
     keep seperate */
  unsigned cannot_combine : 1;


And its access macro:

#define RTX_CANNOT_COMBINE_P(RTX) ((RTX)->cannot_combine)


As well as modify the initializer of global_rtl to add the extra zero...
And then added the following statment to cant_combine_insn_p():

  /* For particular chips with restrictive addressing modes, the
     machine description may split up accesses and then mark the
     instruction.  As an example the ColdFire FPU can't deal with
     absolute addressing, but the ColdFire integer unit can, so the
     m68k.md forces the symbol_ref into a register and uses indirect
     addressing, and marks the instruction as one that can't be
     combined. */
  if (RTX_CANNOT_COMBINE_P (insn))
    return 1;


As well as changed the movdf pattern to:

(define_expand "movdf"
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
	(match_operand:DF 1 "general_operand" ""))]
  ""
  "
{
  rtx insn;

  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 && 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)));
      /* Create the instruciton and set RTX_CANNOT_COMBINE_P to
         prevent the combiner from putting this back together.
      insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
      RTX_CANNOT_COMBINE_P (insn) = 1;
      DONE;
    }
  }
}")


Now the following code:

double x(void)
{
  return 0.5;
}

Compiles into:

	.file	"z.c"
gcc2_compiled.:
.section	.rodata
	.align 	2
.LC0:
	.double 0r5.00000000000000000000e-1
.text
.globl x
	.type	 x,@function
x:
	link.w %a6,#0
	lea .LC0,%a0
	fmove.d (%a0),%fp0
	unlk %a6
	rts

Which looks correct.


My question to you all is whether or not this is a viable approach.
Does anyone have a suggestion for how better to solve this problem?

Thanks in advance for your guidance,

-- 
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] 9+ messages in thread

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

Thread overview: 9+ 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
  -- strict thread matches above, loose matches on Subject: below --
2001-12-07 10:13 Peter Barada
2001-12-07 11:27 ` Alan Lehotsky
2001-12-07 13:01   ` 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).