From: Peter Barada <pbarada@mail.wm.sps.mot.com>
To: gcc@gcc.gnu.org
Cc: Peter.Barada@motorola.com
Subject: Re: Restricted addressing modes in ColdFire FPU for DFmode
Date: Fri, 07 Dec 2001 10:13:00 -0000 [thread overview]
Message-ID: <200112071802.fB7I2cd25266@hyper.wm.sps.mot.com> (raw)
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.
The fmove.d instruction supports only the following addressing modes:
predecrement, postincement, indirect, inderect with offset, and
pc-relative with offset(for loads). Note that neither register direct
nor absolute addressing is supported. I created to following RTL for
movdf:
(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 that split up symbolic addressing quite well(as well as handled constants):
(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))
but the combiner converted that back into:
(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)))
Which died 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))
I looked over combine.c, and I didn't see anyway that a target can
prevent combination from happening. So in desperation I decided to
add a flag to the rtx struct:
/* 1 in an INSN or a SET if this rtx can *not* be combined with
either RTX next to it. Its necessary to limit the combiner from
creating RTX that the machine description worked very hard to
keep seperate */
unsigned cannot_combine : 1;
And its access macro:
#define RTX_CANNOT_COMBINE_P(RTX) ((RTX)->cannot_combine)
As well as modify the initializer of global_rtl to add the extra zero...
And then added the following statment to cant_combine_insn_p():
/* For particular chips with restrictive addressing modes, the
machine description may split up accesses and then mark the
instruction. As an example the ColdFire FPU can't deal with
absolute addressing, but the ColdFire integer unit can, so the
m68k.md forces the symbol_ref into a register and uses indirect
addressing, and marks the instruction as one that can't be
combined. */
if (RTX_CANNOT_COMBINE_P (insn))
return 1;
As well as changed the movdf pattern to:
(define_expand "movdf"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand:DF 1 "general_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)));
/* Create the instruciton and set RTX_CANNOT_COMBINE_P to
prevent the combiner from putting this back together.
insn = emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
RTX_CANNOT_COMBINE_P (insn) = 1;
DONE;
}
}
}")
Now the following code:
double x(void)
{
return 0.5;
}
Compiles into:
.file "z.c"
gcc2_compiled.:
.section .rodata
.align 2
.LC0:
.double 0r5.00000000000000000000e-1
.text
.globl x
.type x,@function
x:
link.w %a6,#0
lea .LC0,%a0
fmove.d (%a0),%fp0
unlk %a6
rts
Which looks correct.
My question to you all is whether or not this is a viable approach.
Does anyone have a suggestion for how better to solve this problem?
Thanks in advance for your guidance,
--
Peter Barada Peter.Barada@motorola.com
Wizard 781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola) 781-270-0193 (fax)
next reply other threads:[~2001-12-07 18:06 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-12-07 10:13 Peter Barada [this message]
2001-12-07 11:27 ` Alan Lehotsky
2001-12-07 13:01 ` Peter Barada
2001-12-07 17:35 Re^2: " Peter Barada
2001-12-08 22:46 ` Richard Henderson
2001-12-10 8:15 ` Peter Barada
2001-12-10 13:11 ` Richard Henderson
2001-12-10 13:59 ` Peter Barada
2001-12-10 15:06 ` Peter Barada
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200112071802.fB7I2cd25266@hyper.wm.sps.mot.com \
--to=pbarada@mail.wm.sps.mot.com \
--cc=Peter.Barada@motorola.com \
--cc=gcc@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).