This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]