This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH [RFC] Fix for long double (TARGET_LONG_DOUBLE_128) on ppc-darwin
- From: Fariborz Jahanian <fjahanian at apple dot com>
- To: "gcc-patches at gcc dot gnu dot org Patches" <gcc-patches at gcc dot gnu dot org>
- Cc: Fariborz Jahanian <fjahanian at apple dot com>
- Date: Mon, 19 Jul 2004 18:15:10 -0700
- Subject: PATCH [RFC] Fix for long double (TARGET_LONG_DOUBLE_128) on ppc-darwin
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(...) !
/* Emit a move from SOURCE to DEST in mode MODE. */
void
rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
...
/* 128-bit constant floating-point values on Darwin should really be
loaded as two parts. */
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
&& mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
{
/* DImode is used, not DFmode, because simplify_gen_subreg doesn't
know how to get a DFmode SUBREG of a TFmode. */
rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
0),
simplify_gen_subreg (DImode, operands[1], mode,
0),
DImode);
rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
GET_MODE_SIZE (DImode)),
simplify_gen_subreg (DImode, operands[1], mode,
GET_MODE_SIZE (DImode)),
DImode);
return;
}
I propose a fix in legitimate_lo_sum_address_p with this patch:
*************** legitimate_lo_sum_address_p (enum machin
*** 3010,3016 ****
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);
--- 3023,3031 ----
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);
Ideally, I would like to make the extra condition restricted to the
pattern generated for load of
a 'long double' literal in registers only. But when call to
legitimate_lo_sum_address_p is made,
no such information is available. Is this the right approach to fix
this problem. Dejagnu test passed
with this patch on apple-ppc-darwin.
- Thanks, Fariborz (fjahanian@apple.com)