This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re^2: Restricted addressing modes in ColdFire FPU for DFmode
- From: Peter Barada <pbarada at mail dot wm dot sps dot mot dot com>
- To: gcc at gcc dot gnu dot org
- Cc: Peter dot Barada at motorola dot com
- Date: Fri, 7 Dec 2001 20:07:31 -0500
- Subject: Re^2: 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.
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)