This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH [mainline] Fix for long double (TARGET_LONG_DOUBLE_128) on ppc-darwin
- From: Geoffrey Keating <geoffk at geoffk dot org>
- To: Fariborz Jahanian <fjahanian at apple dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: 30 Jul 2004 14:17:31 -0700
- Subject: Re: PATCH [mainline] Fix for long double (TARGET_LONG_DOUBLE_128) on ppc-darwin
- References: <ECF25605-DDA1-11D8-85BB-000A2789A51E@apple.com>
Fariborz Jahanian <fjahanian@apple.com> writes:
> This is formal patch for an RFC I sent earlier.
>
> Following test case fails with gcc3.5 on apple-ppc-darwin where 'long
> double' is 128 bits (TARGET_LONG_DOUBLE_128).
>
> extern long double JUNK(long double ld);
> long double xdivcl()
> {
> return JUNK(0.0L);
> }
>
> Following pattern is generated to load 'long double' literal into two
> registers, using DImode:
>
> (insn 8 26 27 0 (set (reg:DI 33 f1)
> (mem/u/c:DI (lo_sum:SI (reg:SI 2 r2)
> (const:SI (minus:SI (symbol_ref/u:SI ("*LC0") [flags 0x2])
> (symbol_ref:SI ("<pic base>"))))) [0 S8 A64])) 327
> {*movdi_internal32} (nil)
> (nil))
>
> ...
>
> (insn 9 27 10 0 (set (reg:DI 34 f2 [orig:33+8 ] [33])
> (mem/u/c:DI (lo_sum:SI (reg:SI 2 r2)
> (const:SI (minus:SI (symbol_ref/u:SI ("*LC0") [flags 0x2])
> (symbol_ref:SI ("<pic base>"))))) [0 S8 A64])) 327
> {*movdi_internal32} (nil)
> (nil))
>
> Above pattern is generated in routine rs6000_emit_move and rejected in
> legitimate_lo_sum_address_p(...).
>
> Attached patch bootstrapped and dejagnu tested on
> apple-ppc-darwin fixes the problem.
>
> OK for FSF mainline?
> - Thanks, Fariborz (fjahanian@apple.com)
I think the second part of this patch won't work. If you get into
rs6000_split_multireg_move with a non-offsettable address, there's no
code you can generate. I'll look into this a bit more and come up
with a patch.
> ChangeLog:
>
> 2004-07-24 Fariborz Jahanian <fjahanian@apple.com>
> * config/rs6000/rs6000.c (legitimate_lo_sum_address_p):
> DImode is legit. mode with lo_sum pic address and when
> long double is 128 bits.
> (rs6000_split_multireg_move): Added case of LO_SUM when
> register node is being obtained.
>
> Patch:
>
> Index: rs6000.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
> retrieving revision 1.671
> diff -c -p -r1.671 rs6000.c
> *** rs6000.c 23 Jul 2004 04:35:17 -0000 1.671
> --- rs6000.c 24 Jul 2004 18:32:19 -0000
> *************** legitimate_lo_sum_address_p (enum machin
> *** 3162,3168 ****
> if (GET_MODE_NUNITS (mode) != 1)
> return false;
> if (GET_MODE_BITSIZE (mode) > 32
> ! && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode))
> return false;
>
> return CONSTANT_P (x);
> --- 3162,3170 ----
> if (GET_MODE_NUNITS (mode) != 1)
> return false;
> if (GET_MODE_BITSIZE (mode) > 32
> ! && !(TARGET_HARD_FLOAT && TARGET_FPRS
> ! && (mode == DFmode ||
> ! (TARGET_LONG_DOUBLE_128 && mode == DImode))))
> return false;
>
> return CONSTANT_P (x);
> *************** rs6000_split_multireg_move (rtx dst, rtx
> *** 11077,11084 ****
> we have change that register last. */
>
> breg = (GET_CODE (XEXP (src, 0)) == PLUS
> ? XEXP (XEXP (src, 0), 0)
> ! : XEXP (src, 0));
>
> if (!REG_P (breg))
> abort();
> --- 11079,11087 ----
> we have change that register last. */
>
> breg = (GET_CODE (XEXP (src, 0)) == PLUS
> + || GET_CODE (XEXP (src, 0)) == LO_SUM)
> ? XEXP (XEXP (src, 0), 0)
> ! : XEXP (src, 0);
>
> if (!REG_P (breg))
> abort();