This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Troubles with CONST_DOUBLE
- From: Peter Barada <pbarada at mail dot wm dot sps dot mot dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 21 Feb 2002 19:17:20 -0500
- Subject: 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)