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]

Troubles with CONST_DOUBLE



I'm still working on adding in the FPU support for ColdFire V4e, and
in this FPU, it can not deal with symbolic addressing or immediate
values.  I got around(I think!) the symbolic addressing by cloning the
reload_insf/df and reload_outsf/df from pa.md, along with most of
emit_move_sequence from pa/pa.c.

but I'm still dealing with unrecognized instructions:

../colorsrv/csmatrix.c:185: unrecognizable insn:
(insn 49 48 51 (set (reg:SF 43)
        (minus:SF (reg:SF 42)
            (const_double:SF 0 [0x0] 0 [0x0] 0 [0x0]))) -1 (insn_list 48 (nil))
    (expr_list:REG_DEAD (reg:SF 42)
        (nil)))

To fix this, I modified LEGITIMATE_CONSTANT_P to reject any CONST_DOUBLE:

/* Nonzero if the constant value X is a legitimate general operand.
   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
   If we're on ColdFire v4e, reject const_doubles since the FPU insns
   can't take them as operands.   */
#define LEGITIMATE_CONSTANT_P(X) \
(!TARGET_CFV4E || GET_CODE(X) != CONST_DOUBLE)


And this removes the errors, but when I try to compile the code:

extern void barf(char);
void foo(float *tabp)
{
  char s;

  if ((s = ((tabp[0]) < 0)) == 0)
    {
      barf(s);
    }
}

It generates the code:

foo:
	link.w %a6,#0
	move.l 8(%a6),%a1	| 53	cfv4_movsi/1
	ftst.s (%a1)	| 19	tstsf_v4e
	fslt %d0	| 48	*slt
	moveq.l #1,%d1	| 57	cfv4_movsi/1
	and.l %d1,%d0	| 49	andsi3_5200/2
	move.b %d0,%d1	| 50	cfv4_movqi/1
	jbne .L1	| 26	bne
	moveq.l #1,%d0	| 60	cfv4_movsi/1
	and.l %d1,%d0	| 32	andsi3_5200/2
	move.l %d0,-(%sp)	| 63	cfv4_movsi/1
	jbsr barf	| 35	*m68k.md:8117
	addq.l #4,%sp	| 36	*addsi3_5200/2
	.stabn 68,0,11,.LM4-foo
	unlk %a6
	rts

Which is all good except for the 'fslt' instruction which the v4e FPU
doesn't support.  I disabled that pattern by modifying its pattern:

(define_expand "slt"
  [(set (match_operand:QI 0 "register_operand" "")
	(lt:QI (cc0) (const_int 0)))]
  ""
  "
{
  if ((TARGET_68060 || TARGET_CFV4E) && m68k_last_compare_had_fp_operands)
    {
      m68k_last_compare_had_fp_operands = 0;
      FAIL;
    }
}")

(define_insn "*slt"
  [(set (match_operand:QI 0 "register_operand" "=d")
	(lt:QI (cc0) (const_int 0)))]
  ""
  "*
   cc_status = cc_prev_status;
   OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")


Which should fail since TARGET_CFV4E is true.

But it still shows up.  I ran it through the debugger, and I see that
this pattern is rejected, repeatedly, and at the point that the fslt
instruction pattern is being selected, the instruction stream looks like:

(gdb) call debug_rtx_list(insn,-2)
(insn:QI 19 53 48 (set (cc0)
        (mem:SF (reg:SI 9 %a1 [29]) [3 S4 A32])) 8 {tstsf_v4e} (insn_list 53 (nil))
    (expr_list:REG_DEAD (reg:SI 9 %a1 [29])
        (nil)))

(insn 48 19 57 (set (reg:QI 0 %d0 [37])
        (lt:QI (cc0)
            (const_int 0 [0x0]))) 344 {*slt} (nil)
    (expr_list:REG_EQUIV (lt:QI (cc0)
            (const_int 0 [0x0]))
        (nil)))


1) Is making LEGITIMATE_CONSTANT_P return false for CONST_DOUBLE the
   right way to prevent constants from being using in the float/double
   patterns? 

2) If so, why is it generated the 'fslt' instruction when I disabled it?

Thanx,

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