public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: How to force register indirect addressing of global FP variables
@ 2001-12-06 13:13 Peter Barada
  0 siblings, 0 replies; only message in thread
From: Peter Barada @ 2001-12-06 13:13 UTC (permalink / raw)
  To: gcc


The Coldfire FPU can't deal with absolute addressing, or immediate
values, so constants have to be loaded out of memory.  I decided to
carve this problem up into two parts.  First I'll get gcc-2.95.3 to
generate RTL to leave the DPFP constants in memory.  Later I'll figure
out how to deal with better methods of addressing the DPFP constants.

I'm running into a problem where the instruction combination pass is
putting back together the RTL that I split up.

The rtl I have so far looks like(the 'Q' constraint is register indirect): 


(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 when I try to compile:

double x(void)
{
  return (0.5);
}


I get the following .c.rtl:


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

(insn 10 9 11 (use (reg/i:DF 16 %fp0)) -1 (nil)
    (nil))


Which looks correct, but the two are merged by the combiner back into:

;; Start of basic block 0, registers live: 14 [%a6] 15 [%sp]
(note 17 6 8 [bb 0] NOTE_INSN_BASIC_BLOCK)

(note 8 17 9 "" NOTE_INSN_DELETED)

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

(insn 10 9 0 (use (reg/i:DF 16 %fp0)) -1 (insn_list 9 (nil))
    (expr_list:REG_DEAD (reg/i:DF 16 %fp0)
        (nil)))
;; End of basic block 0


And the whole compilation fails 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))


How can I convince the combiner that it shouldn't merge these two
insns into one???

-- 
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] only message in thread

only message in thread, other threads:[~2001-12-06 21:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-06 13:13 How to force register indirect addressing of global FP variables 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).