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: Restricted addressing modes in ColdFire FPU for DFmode



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


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